[gparted] Refactor alternate_paths logic into new Proc_Partitions_Info class



commit 319255d3bc8b59f5f9e1f73ed1eb4b49a9aee0a9
Author: Curtis Gedak <gedakc gmail com>
Date:   Tue Dec 7 11:49:50 2010 -0700

    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.

 include/GParted_Core.h         |    3 -
 include/Makefile.am            |    1 +
 include/Proc_Partitions_Info.h |   48 ++++++++++++++++++
 src/GParted_Core.cc            |   50 ++-----------------
 src/Makefile.am                |    1 +
 src/Proc_Partitions_Info.cc    |  104 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 160 insertions(+), 47 deletions(-)
---
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index 0b5f8fb..e1656d8 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -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 ;
diff --git a/include/Makefile.am b/include/Makefile.am
index 26bd12f..030e59f 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -30,6 +30,7 @@ EXTRA_DIST = \
 	OperationResizeMove.h		\
 	OperationLabelPartition.h	\
 	Partition.h  			\
+	Proc_Partitions_Info.h	\
 	SWRaid.h				\
 	TreeView_Detail.h 		\
 	Utils.h 			\
diff --git a/include/Proc_Partitions_Info.h b/include/Proc_Partitions_Info.h
new file mode 100644
index 0000000..1f0c86a
--- /dev/null
+++ b/include/Proc_Partitions_Info.h
@@ -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_*/
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index a94b672..f142cac 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -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() ;
diff --git a/src/Makefile.am b/src/Makefile.am
index b42000a..c76ec37 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,6 +39,7 @@ gpartedbin_SOURCES = \
 	OperationResizeMove.cc		\
 	OperationLabelPartition.cc	\
 	Partition.cc			\
+	Proc_Partitions_Info.cc		\
 	SWRaid.cc				\
 	TreeView_Detail.cc		\
 	Utils.cc			\
diff --git a/src/Proc_Partitions_Info.cc b/src/Proc_Partitions_Info.cc
new file mode 100644
index 0000000..0595c01
--- /dev/null
+++ b/src/Proc_Partitions_Info.cc
@@ -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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]