Refactor alternate_paths logic into new Proc_Partitions_Info class

This reason for refactoring is to simplify the large GParted_Core
class, to help minimize disk reads, and to group the logic for
processing the file /proc/partitions into a single logical class.
This commit is contained in:
Curtis Gedak 2010-12-07 11:49:50 -07:00
parent f563df0942
commit 319255d3bc
6 changed files with 160 additions and 47 deletions

View File

@ -65,7 +65,6 @@ private:
void read_mountpoints_from_file_swaps(
const Glib::ustring & filename,
std::map< Glib::ustring, std::vector<Glib::ustring> > & map ) ;
std::vector<Glib::ustring> get_alternate_paths( const Glib::ustring & path ) ;
Glib::ustring get_partition_path( PedPartition * lp_partition ) ;
void set_device_partitions( Device & device ) ;
GParted::FILESYSTEM get_filesystem() ;
@ -202,8 +201,6 @@ private:
std::map< Glib::ustring, std::vector<Glib::ustring> > mount_info ;
std::map< Glib::ustring, std::vector<Glib::ustring> > fstab_info ;
std::map< Glib::ustring, Glib::ustring > alternate_paths ;
std::map< Glib::ustring, Glib::ustring >::iterator iter ;
std::map< Glib::ustring, std::vector<Glib::ustring> >::iterator iter_mp ;
PedDevice *lp_device ;

View File

@ -30,6 +30,7 @@ EXTRA_DIST = \
OperationResizeMove.h \
OperationLabelPartition.h \
Partition.h \
Proc_Partitions_Info.h \
SWRaid.h \
TreeView_Detail.h \
Utils.h \

View File

@ -0,0 +1,48 @@
/* Copyright (C) 2010 Curtis Gedak
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Proc_Partitions_Info
*
* A persistent cache of information from the file /proc/partitions
* that helps to minimize the number of required disk reads.
*/
#ifndef PROC_PARTITONS_INFO_H_
#define PROC_PARTITONS_INFO_H_
#include "../include/Utils.h"
namespace GParted
{
class Proc_Partitions_Info
{
public:
Proc_Partitions_Info() ;
Proc_Partitions_Info( bool do_refresh ) ;
~Proc_Partitions_Info() ;
std::vector<Glib::ustring> get_alternate_paths( const Glib::ustring & path ) ;
private:
void load_proc_partitions_info_cache() ;
static bool proc_partitions_info_cache_initialized ;
static std::map< Glib::ustring, Glib::ustring > alternate_paths_cache ;
};
}//GParted
#endif /*PROC_PARTITONS_INFO_H_*/

View File

@ -27,6 +27,7 @@
#include "../include/OperationFormat.h"
#include "../include/OperationResizeMove.h"
#include "../include/OperationLabelPartition.h"
#include "../include/Proc_Partitions_Info.h"
#include "../include/btrfs.h"
#include "../include/ext2.h"
@ -156,6 +157,7 @@ void GParted_Core::set_devices( std::vector<Device> & devices )
{
devices .clear() ;
Device temp_device ;
Proc_Partitions_Info pp_info( true ) ; //Refresh cache of proc partition information
FS_Info fs_info( true ) ; //Refresh cache of file system information
DMRaid dmraid( true ) ; //Refresh cache of dmraid device information
SWRaid swraid( true ) ; //Refresh cache of swraid device information
@ -297,7 +299,7 @@ void GParted_Core::set_devices( std::vector<Device> & devices )
//device info..
temp_device .add_path( device_paths[ t ] ) ;
temp_device .add_paths( get_alternate_paths( temp_device .get_path() ) ) ;
temp_device .add_paths( pp_info .get_alternate_paths( temp_device .get_path() ) ) ;
temp_device .model = lp_device ->model ;
temp_device .length = lp_device ->length ;
@ -363,7 +365,6 @@ void GParted_Core::set_devices( std::vector<Device> & devices )
//clear leftover information...
//NOTE that we cannot clear mountinfo since it might be needed in get_all_mountpoints()
set_thread_status_message("") ;
alternate_paths .clear() ;
fstab_info .clear() ;
}
@ -743,7 +744,6 @@ Glib::ustring GParted_Core::get_libparted_version()
void GParted_Core::init_maps()
{
alternate_paths .clear() ;
mount_info .clear() ;
fstab_info .clear() ;
@ -761,34 +761,6 @@ void GParted_Core::init_maps()
std::unique( iter_mp ->second .begin(), iter_mp ->second .end() ),
iter_mp ->second .end() ) ;
}
//initialize alternate_paths...
std::string line ;
std::ifstream proc_partitions( "/proc/partitions" ) ;
if ( proc_partitions )
{
char c_str[4096+1] ;
while ( getline( proc_partitions, line ) )
if ( sscanf( line .c_str(), "%*d %*d %*d %4096s", c_str ) == 1 )
{
line = "/dev/" ;
line += c_str ;
//FIXME: it seems realpath is very unsafe to use (manpage)...
if ( file_test( line, Glib::FILE_TEST_EXISTS ) &&
realpath( line .c_str(), c_str ) &&
line != c_str )
{
//because we can make no assumption about which path libparted will detect
//we add all combinations.
alternate_paths[ c_str ] = line ;
alternate_paths[ line ] = c_str ;
}
}
proc_partitions .close() ;
}
}
void GParted_Core::read_mountpoints_from_file(
@ -850,17 +822,6 @@ void GParted_Core::read_mountpoints_from_file_swaps(
}
}
std::vector<Glib::ustring> GParted_Core::get_alternate_paths( const Glib::ustring & path )
{
std::vector<Glib::ustring> paths ;
iter = alternate_paths .find( path ) ;
if ( iter != alternate_paths .end() )
paths .push_back( iter ->second ) ;
return paths ;
}
Glib::ustring GParted_Core::get_partition_path( PedPartition * lp_partition )
{
DMRaid dmraid; //Use cache of dmraid device information
@ -888,6 +849,7 @@ Glib::ustring GParted_Core::get_partition_path( PedPartition * lp_partition )
void GParted_Core::set_device_partitions( Device & device )
{
int EXT_INDEX = -1 ;
Proc_Partitions_Info pp_info ; //Use cache of proc partitions information
FS_Info fs_info ; //Use cache of file system information
DMRaid dmraid ; //Use cache of dmraid device information
@ -936,7 +898,7 @@ void GParted_Core::set_device_partitions( Device & device )
lp_partition ->type,
partition_is_busy ) ;
partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ;
partition_temp .add_paths( pp_info .get_alternate_paths( partition_temp .get_path() ) ) ;
set_flags( partition_temp ) ;
if ( partition_temp .busy && partition_temp .partition_number > device .highest_busy )
@ -976,7 +938,7 @@ void GParted_Core::set_device_partitions( Device & device )
false,
partition_is_busy ) ;
partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ;
partition_temp .add_paths( pp_info .get_alternate_paths( partition_temp .get_path() ) ) ;
set_flags( partition_temp ) ;
EXT_INDEX = device .partitions .size() ;

View File

@ -39,6 +39,7 @@ gpartedbin_SOURCES = \
OperationResizeMove.cc \
OperationLabelPartition.cc \
Partition.cc \
Proc_Partitions_Info.cc \
SWRaid.cc \
TreeView_Detail.cc \
Utils.cc \

104
src/Proc_Partitions_Info.cc Normal file
View File

@ -0,0 +1,104 @@
/* Copyright (C) 2010 Curtis Gedak
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Proc_Partitions_Info.h"
#include <fstream>
namespace GParted
{
//Initialize static data elements
bool Proc_Partitions_Info::proc_partitions_info_cache_initialized = false ;
std::map< Glib::ustring, Glib::ustring > Proc_Partitions_Info::alternate_paths_cache ;
Proc_Partitions_Info::Proc_Partitions_Info()
{
//Ensure that cache has been loaded at least once
if ( ! proc_partitions_info_cache_initialized )
{
proc_partitions_info_cache_initialized = true ;
load_proc_partitions_info_cache() ;
}
}
Proc_Partitions_Info::Proc_Partitions_Info( bool do_refresh )
{
//Ensure that cache has been loaded at least once
if ( ! proc_partitions_info_cache_initialized )
{
proc_partitions_info_cache_initialized = true ;
if ( do_refresh == false )
load_proc_partitions_info_cache() ;
}
if ( do_refresh )
load_proc_partitions_info_cache() ;
}
Proc_Partitions_Info::~Proc_Partitions_Info()
{
}
std::vector<Glib::ustring> Proc_Partitions_Info::get_alternate_paths( const Glib::ustring & path )
{
std::vector<Glib::ustring> paths ;
std::map< Glib::ustring, Glib::ustring >::iterator iter ;
iter = alternate_paths_cache .find( path ) ;
if ( iter != alternate_paths_cache .end() )
paths .push_back( iter ->second ) ;
return paths ;
}
//Private Methods
void Proc_Partitions_Info::load_proc_partitions_info_cache()
{
alternate_paths_cache .clear();
//Initialize alternate_paths
std::string line ;
std::ifstream proc_partitions( "/proc/partitions" ) ;
if ( proc_partitions )
{
char c_str[4096+1] ;
while ( getline( proc_partitions, line ) )
if ( sscanf( line .c_str(), "%*d %*d %*d %4096s", c_str ) == 1 )
{
line = "/dev/" ;
line += c_str ;
//FIXME: it seems realpath is very unsafe to use (manpage)...
if ( file_test( line, Glib::FILE_TEST_EXISTS )
&& realpath( line .c_str(), c_str )
//&& line != c_str
)
{
//Because we can make no assumption about which path libparted will
//detect, we add all combinations.
alternate_paths_cache[ c_str ] = line ;
alternate_paths_cache[ line ] = c_str ;
}
}
proc_partitions .close() ;
}
}
}//GParted