Cache looked up major, minor numbers in BlockSpecial class (#767842)
Creation of every BlockSpecial object used to result in a stat() OS call. On one of my test VMs debugging with 4 disks and a few partitions on each, GParted refresh generated 541 calls to stat() in the BlockSpecial(name) constructor. However there were only 45 unique names. So on average each name was stat()ed approximately 12 times. Cache the major, minor number associated with each name after starting with a cleared cache for each GParted refresh. This reduces these direct calls to stat() to just the 45 unique names. Bug 767842 - File system usage missing when tools report alternate block device names
This commit is contained in:
parent
ce8fb1dd91
commit
003d6eff94
|
@ -41,6 +41,8 @@ public:
|
|||
Glib::ustring m_name; // E.g. Block special file {"/dev/sda1", 8, 1},
|
||||
unsigned long m_major; // plain file {"FILENAME", 0, 0} and empty object
|
||||
unsigned long m_minor; // {"", 0, 0}.
|
||||
|
||||
static void clear_cache();
|
||||
};
|
||||
|
||||
// Operator overloading > The Decision between Member and Non-member
|
||||
|
|
|
@ -20,28 +20,65 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
|
||||
namespace GParted
|
||||
{
|
||||
|
||||
struct MM_Number
|
||||
{
|
||||
unsigned long m_major;
|
||||
unsigned long m_minor;
|
||||
};
|
||||
|
||||
typedef std::map<Glib::ustring, MM_Number> MMNumberMapping;
|
||||
|
||||
// Associative array caching name to major, minor number pairs
|
||||
// E.g.
|
||||
// mm_number_cache["/dev/sda"] = {8, 0}
|
||||
// mm_number_cache["/dev/sda1"] = {8, 1}
|
||||
// mm_number_cache["proc"] = {0, 0}
|
||||
// mm_number_cache["sysfs"] = {0, 0}
|
||||
static MMNumberMapping mm_number_cache;
|
||||
|
||||
BlockSpecial::BlockSpecial() : m_name( "" ), m_major( 0UL ), m_minor( 0UL )
|
||||
{
|
||||
}
|
||||
|
||||
BlockSpecial::BlockSpecial( const Glib::ustring & name ) : m_name( name ), m_major( 0UL ), m_minor( 0UL )
|
||||
{
|
||||
MMNumberMapping::const_iterator mm_num_iter = mm_number_cache.find( name );
|
||||
if ( mm_num_iter != mm_number_cache.end() )
|
||||
{
|
||||
// Use already cached major, minor pair
|
||||
m_major = mm_num_iter->second.m_major;
|
||||
m_minor = mm_num_iter->second.m_minor;
|
||||
return;
|
||||
}
|
||||
|
||||
MM_Number pair = {0UL, 0UL};
|
||||
// Call stat(name, ...) to get the major, minor pair
|
||||
struct stat sb;
|
||||
if ( stat( name.c_str(), &sb ) == 0 && S_ISBLK( sb.st_mode ) )
|
||||
{
|
||||
m_major = major( sb.st_rdev );
|
||||
m_minor = minor( sb.st_rdev );
|
||||
pair.m_major = m_major;
|
||||
pair.m_minor = m_minor;
|
||||
}
|
||||
// Add new cache entry for name to major, minor pair
|
||||
mm_number_cache[name] = pair;
|
||||
}
|
||||
|
||||
BlockSpecial::~BlockSpecial()
|
||||
{
|
||||
}
|
||||
|
||||
void BlockSpecial::clear_cache()
|
||||
{
|
||||
mm_number_cache.clear();
|
||||
}
|
||||
|
||||
bool operator==( const BlockSpecial & lhs, const BlockSpecial & rhs )
|
||||
{
|
||||
if ( lhs.m_major > 0UL && lhs.m_minor > 0UL )
|
||||
|
|
|
@ -166,6 +166,9 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
|
|||
std::vector<Device> &devices = *pdevices;
|
||||
devices .clear() ;
|
||||
Device temp_device ;
|
||||
BlockSpecial::clear_cache(); // MUST BE FIRST. Cache of name to major, minor
|
||||
// numbers incrementally loaded when BlockSpecial
|
||||
// objects are created in the following caches.
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue