diff options
author | Sage Weil <sage@newdream.net> | 2012-05-02 12:09:12 -0700 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2012-05-02 14:55:53 -0700 |
commit | 8220ab251bb59a6b274dbd9456d129aef48a0c30 (patch) | |
tree | 5e420acbaa7010c36c05af321801b0907a535a88 | |
parent | bfa7635162566ccbf3a3ab326a71024836a146f6 (diff) | |
download | ceph-8220ab251bb59a6b274dbd9456d129aef48a0c30.tar.gz |
crush: implement update_item()
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>
-rw-r--r-- | src/crush/CrushWrapper.cc | 38 | ||||
-rw-r--r-- | src/crush/CrushWrapper.h | 6 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 5473e60a85d..396fcfacde0 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -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; diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 25ada59d12e..3db2a23c34a 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -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 { |