Project

General

Profile

Bug #13530

Updated by Kefu Chai over 8 years ago

<pre> 
 int HashIndex::_remove(const vector<string> &path, 
		        const ghobject_t &oid, 
		        const string &mangled_name) { 
   int r; 
   r = remove_object(path, oid); 
   if (r < 0) 
     return r; 
   subdir_info_s info; 
   r = get_info(path, &info); 
   if (r < 0) 
     return r; 
   info.objs--; 
   r = set_info(path, info); 
   if (r < 0) 
     return r; 
   if (must_merge(info)) { 
   ... 
 </pre> 

 


 See above, if we delete an object from the current dirent, a check for whether this dirent's containing objects dropping below the merge_threshold is performed. And if it does, a merge of current dirent to it's parent dirent will be kicked off. 

 I think this code logic can be a little bit problematic for the following reason: 
 Suppose we have a dirent-A, say, which consists of: 
 1.    subdir-0( which has 0 subdir and 9 objects) 
 2.    subdir-1( which has 0 subdir and 100 objects) 
 3.    154 objects 

 Now we reset merge_threshold to 10 and split_multiplier to 1, and we know if we delete a object from subdir-0, a merge shall occur. As a result, subdir-0 is removed and all its containing objects goes into dirent-A which now has 1 subdir and 162(154 + 8) objects. 

 However, if we try to add another new object to dirent-A later, it will trigger a split immediately and the subdir-0 is recreated and all it's previous objects are re-claimed.  

 From the above scenario, we now see the cost of the merge may be very expensive and thus shall be avoided. 


 






Back