]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: implement update_item()
authorSage Weil <sage@newdream.net>
Wed, 2 May 2012 19:09:12 +0000 (12:09 -0700)
committerSage Weil <sage@newdream.net>
Wed, 2 May 2012 21:55:53 +0000 (14:55 -0700)
This is similar to insert_item(), except it will succeed if the item is
already there, and will move an item to the specified location if it is
not.  It returns 0 for no change, 1 if a chance was made.  It also makes
sure the weight and name match.

Signed-off-by: Sage Weil <sage@newdream.net>
src/crush/CrushWrapper.cc
src/crush/CrushWrapper.h

index 5473e60a85d7e6f3ef9e9040eb35114760261677..396fcfacde0d0c019e742c10d597466b4979aa55 100644 (file)
@@ -119,7 +119,7 @@ bool CrushWrapper::check_item_loc(CephContext *cct, int item, map<string,string>
 }
 
 int CrushWrapper::insert_item(CephContext *cct, int item, float weight, string name,
-                               map<string,string>& loc)  // typename -> bucketname
+                             map<string,string>& loc)  // typename -> bucketname
 {
   ldout(cct, 5) << "insert_item item " << item << " weight " << weight
                << " name " << name << " loc " << loc << dendl;
@@ -184,6 +184,42 @@ int CrushWrapper::insert_item(CephContext *cct, int item, float weight, string n
   return -EINVAL;
 }
 
+int CrushWrapper::update_item(CephContext *cct, int item, float weight, string name,
+                             map<string,string>& loc)  // typename -> bucketname
+{
+  ldout(cct, 5) << "update_item item " << item << " weight " << weight
+               << " name " << name << " loc " << loc << dendl;
+  int ret = 0;
+
+  weight = quantize_weight(weight);
+
+  float old_weight;
+  if (check_item_loc(cct, item, loc, &old_weight)) {
+    ldout(cct, 5) << "update_item " << item << " already at " << loc << dendl;
+    if (old_weight != weight) {
+      ldout(cct, 5) << "update_item " << item << " adjusting weight "
+                   << old_weight << " -> " << weight << dendl;
+      adjust_item_weightf(cct, item, weight);
+      ret = 1;
+    }
+    if (get_item_name(item) != name) {
+      ldout(cct, 5) << "update_item setting " << item << " name to " << name << dendl;
+      set_item_name(item, name.c_str());
+      ret = 1;
+    }
+  } else {
+    if (item_exists(item)) {
+      remove_item(cct, item);
+    }
+    ldout(cct, 5) << "update_item adding " << item << " weight " << weight
+                 << " at " << loc << dendl;
+    int r = insert_item(cct, item, weight, name.c_str(), loc);
+    if (r == 0)
+      ret = 1;
+  }
+  return ret;
+}
+
 int CrushWrapper::adjust_item_weight(CephContext *cct, int id, int weight)
 {
   ldout(cct, 5) << "adjust_item_weight " << id << " weight " << weight << dendl;
index 25ada59d12e8c0dbfe529a25850b9d585f85b5bf..3db2a23c34a682a51566a29c9a241f5fef35ba61 100644 (file)
@@ -166,6 +166,7 @@ public:
   void find_roots(set<int>& roots) const;
   bool check_item_loc(CephContext *cct, int item, map<string,string>& loc, float *weight);
   int insert_item(CephContext *cct, int id, float weight, string name, map<string,string>& loc);
+  int update_item(CephContext *cct, int id, float weight, string name, map<string,string>& loc);
   int remove_item(CephContext *cct, int id);
   int adjust_item_weight(CephContext *cct, int id, int weight);
   int adjust_item_weightf(CephContext *cct, int id, float weight) {
@@ -173,6 +174,11 @@ public:
   }
   void reweight(CephContext *cct);
 
+  static float quantize_weight(float weight) {
+    int w = (int)(weight * (float)0x10000);
+    return (float)w / (float)0x10000;
+  }
+
 
   /*** devices ***/
   int get_max_devices() const {