]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Cache hobject filestore_key to avoid massive _reverse_nibbles calls 2579/head
authorDong Yuan <yuandong1222@gmail.com>
Tue, 23 Sep 2014 07:14:14 +0000 (07:14 +0000)
committerDong Yuan <yuandong1222@gmail.com>
Fri, 5 Dec 2014 10:32:09 +0000 (10:32 +0000)
Signed-off-by: Dong Yuan <yuandong1222@gmail.com>
13 files changed:
src/common/hobject.cc
src/common/hobject.h
src/os/DBObjectMap.cc
src/os/FDCache.h
src/os/GenericObjectMap.cc
src/os/HashIndex.cc
src/os/LFNIndex.cc
src/osd/HitSet.h
src/osd/PGLog.cc
src/osd/ReplicatedPG.cc
src/osd/osd_types.cc
src/test/objectstore/store_test.cc
src/test/osd/TestPGLog.cc

index 00b00195601dde4b34f59f108b65844183a34374..fda169bf6d6777a1af825aadb2290b4caedd6a49 100644 (file)
@@ -132,6 +132,7 @@ void hobject_t::decode(bufferlist::iterator& bl)
     ::decode(pool, bl);
   }
   DECODE_FINISH(bl);
+  build_filestore_key_cache();
 }
 
 void hobject_t::decode(json_spirit::Value& v)
@@ -155,6 +156,7 @@ void hobject_t::decode(json_spirit::Value& v)
     else if (p.name_ == "namespace")
       nspace = p.value_.get_str();
   }
+  build_filestore_key_cache();
 }
 
 void hobject_t::dump(Formatter *f) const
@@ -184,7 +186,7 @@ ostream& operator<<(ostream& out, const hobject_t& o)
 {
   if (o.is_max())
     return out << "MAX";
-  out << std::hex << o.hash << std::dec;
+  out << std::hex << o.get_hash() << std::dec;
   if (o.get_key().length())
     out << "." << o.get_key();
   out << "/" << o.oid << "/" << o.snap;
@@ -233,6 +235,7 @@ void ghobject_t::decode(bufferlist::iterator& bl)
     shard_id = shard_id_t::NO_SHARD;
   }
   DECODE_FINISH(bl);
+  hobj.set_hash(hobj.get_hash()); //to call build_filestore_key_cache();
 }
 
 void ghobject_t::decode(json_spirit::Value& v)
index 831228007f2552950bf681b7ed85c5562be72dca..ea7a3b666f31e7b1a227fa3bbb2d37ed6cb65a5a 100644 (file)
@@ -32,9 +32,10 @@ namespace ceph {
 struct hobject_t {
   object_t oid;
   snapid_t snap;
-  uint32_t hash;
 private:
+  uint32_t hash;
   bool max;
+  filestore_hobject_key_t filestore_key_cache;
   static const int64_t POOL_IS_TEMP = -1;
 public:
   int64_t pool;
@@ -49,6 +50,14 @@ public:
   }
 
   string to_str() const;
+  
+  uint32_t get_hash() const { 
+    return hash;
+  }
+  void set_hash(uint32_t value) { 
+    hash = value;
+    build_filestore_key_cache();
+  }
 
   static bool match_hash(uint32_t to_check, uint32_t bits, uint32_t match) {
     return (match & ~((~0)<<bits)) == (to_check & ~((~0)<<bits));
@@ -65,26 +74,32 @@ public:
     return pool == POOL_IS_TEMP;
   }
   
-  hobject_t() : snap(0), hash(0), max(false), pool(-1) {}
+  hobject_t() : snap(0), hash(0), max(false), pool(-1) {
+    build_filestore_key_cache();
+  }
 
   hobject_t(object_t oid, const string& key, snapid_t snap, uint64_t hash,
            int64_t pool, string nspace) :
     oid(oid), snap(snap), hash(hash), max(false),
     pool(pool), nspace(nspace),
-    key(oid.name == key ? string() : key) {}
+    key(oid.name == key ? string() : key) {
+        build_filestore_key_cache();
+    }
 
   hobject_t(const sobject_t &soid, const string &key, uint32_t hash,
            int64_t pool, string nspace) :
     oid(soid.oid), snap(soid.snap), hash(hash), max(false),
     pool(pool), nspace(nspace),
-    key(soid.oid.name == key ? string() : key) {}
+    key(soid.oid.name == key ? string() : key) {
+        build_filestore_key_cache();
+    }
 
   /// @return min hobject_t ret s.t. ret.hash == this->hash
   hobject_t get_boundary() const {
     if (is_max())
       return *this;
     hobject_t ret;
-    ret.hash = hash;
+    ret.set_hash(hash);
     return ret;
   }
 
@@ -125,7 +140,7 @@ public:
   /* Do not use when a particular hash function is needed */
   explicit hobject_t(const sobject_t &o) :
     oid(o.oid), snap(o.snap), max(false), pool(-1) {
-    hash = CEPH_HASH_NAMESPACE::hash<sobject_t>()(o);
+    set_hash(CEPH_HASH_NAMESPACE::hash<sobject_t>()(o));
   }
 
   // maximum sorted value.
@@ -170,10 +185,10 @@ public:
     return _reverse_nibbles(hash);
   }
   filestore_hobject_key_t get_filestore_key() const {
-    if (max)
-      return 0x100000000ull;
-    else
-      return get_filestore_key_u32();
+    return max ? 0x100000000ull : filestore_key_cache;
+  }
+  void build_filestore_key_cache() {    
+    filestore_key_cache = _reverse_nibbles(hash);
   }
 
   const string& get_effective_key() const {
@@ -258,7 +273,7 @@ public:
     if (hobj.is_max())
       return *this;
     ghobject_t ret;
-    ret.hobj.hash = hobj.hash;
+    ret.hobj.set_hash(hobj.hash);
     return ret;
   }
   filestore_hobject_key_t get_filestore_key_u32() const {
index c5a5b69c95b670bb1af14e925b736855280bb9ee..27d72f336682fa8113d11bf6c458f33ef60bf019 100644 (file)
@@ -154,7 +154,7 @@ string DBObjectMap::ghobject_key(const ghobject_t &oid)
     t += snprintf(t, end - t, ".none");
   else
     t += snprintf(t, end - t, ".%llx", (long long unsigned)oid.hobj.pool);
-  snprintf(t, end - t, ".%.*X", (int)(sizeof(oid.hobj.hash)*2), oid.hobj.hash);
+  snprintf(t, end - t, ".%.*X", (int)(sizeof(oid.hobj.get_hash())*2), oid.hobj.get_hash());
 
   if (oid.generation != ghobject_t::NO_GEN ||
       oid.shard_id != shard_id_t::NO_SHARD) {
@@ -184,7 +184,7 @@ string DBObjectMap::ghobject_key_v0(coll_t c, const ghobject_t &oid)
     t += snprintf(t, end - t, ".snapdir");
   else
     t += snprintf(t, end - t, ".%llx", (long long unsigned)oid.hobj.snap);
-  snprintf(t, end - t, ".%.*X", (int)(sizeof(oid.hobj.hash)*2), oid.hobj.hash);
+  snprintf(t, end - t, ".%.*X", (int)(sizeof(oid.hobj.get_hash())*2), oid.hobj.get_hash());
   out += string(snap_with_hash);
   return out;
 }
index 9e77873c3227afd061274603d5186aabf1f99ea8..8597265bbf125f5530f2814bfdd1e81ddc5ab706 100644 (file)
@@ -73,18 +73,18 @@ public:
   typedef ceph::shared_ptr<FD> FDRef;
 
   FDRef lookup(const ghobject_t &hoid) {
-    int registry_id = hoid.hobj.hash % registry_shards;
+    int registry_id = hoid.hobj.get_hash() % registry_shards;
     return registry[registry_id].lookup(hoid);
   }
 
   FDRef add(const ghobject_t &hoid, int fd, bool *existed) {
-    int registry_id = hoid.hobj.hash % registry_shards;
+    int registry_id = hoid.hobj.get_hash() % registry_shards;
     return registry[registry_id].add(hoid, new FD(fd), existed);
   }
 
   /// clear cached fd for hoid, subsequent lookups will get an empty FD
   void clear(const ghobject_t &hoid) {
-    int registry_id = hoid.hobj.hash % registry_shards;
+    int registry_id = hoid.hobj.get_hash() % registry_shards;
     registry[registry_id].purge(hoid);
   }
 
index e2c8a2717917868551635abe29527ffaa194c677..67a15d2f1505712c97bc3e9d4ef5855436436cca 100644 (file)
@@ -114,7 +114,7 @@ string GenericObjectMap::header_key(const coll_t &cid, const ghobject_t &oid)
   char *end = t + sizeof(buf);
 
   // make field ordering match with hobject_t compare operations
-  snprintf(t, end - t, "%.*X", (int)(sizeof(oid.hobj.hash)*2),
+  snprintf(t, end - t, "%.*X", (int)(sizeof(oid.hobj.get_hash())*2),
            (uint32_t)oid.get_filestore_key_u32());
   full_name += string(buf);
   full_name.append(GHOBJECT_KEY_SEP_S);
@@ -260,7 +260,7 @@ bool GenericObjectMap::parse_header_key(const string &long_name,
     (*out) = ghobject_t(hobject_t(name, key, snap, hash, (int64_t)pool, ns),
                         generation, shard_id);
     // restore reversed hash. see calculate_key
-    out->hobj.hash = out->get_filestore_key();
+    out->hobj.set_hash(out->get_filestore_key());
   }
 
   if (out_coll)
index a4d1d6c94d8442df7c178812d450e0c8f8243f0a..ead95b4024e60beb489097c8df7eb751e4cdef10 100644 (file)
@@ -748,7 +748,7 @@ string HashIndex::get_hash_str(uint32_t hash) {
 
 string HashIndex::get_path_str(const ghobject_t &oid) {
   assert(!oid.is_max());
-  return get_hash_str(oid.hobj.hash);
+  return get_hash_str(oid.hobj.get_hash());
 }
 
 uint32_t HashIndex::hash_prefix_to_hash(string prefix) {
index c480e6e7cbd3ec5157fd2470a3161b26456e884c..5d6bd7b9d8d7cfd1ed138006205fa53cff2ab855 100644 (file)
@@ -604,7 +604,7 @@ string LFNIndex::lfn_generate_object_name_keyless(const ghobject_t &oid)
     t += snprintf(t, end - t, "_snapdir");
   else
     t += snprintf(t, end - t, "_%llx", (long long unsigned)oid.hobj.snap);
-  snprintf(t, end - t, "_%.*X", (int)(sizeof(oid.hobj.hash)*2), oid.hobj.hash);
+  snprintf(t, end - t, "_%.*X", (int)(sizeof(oid.hobj.get_hash())*2), oid.hobj.get_hash());
 
   return string(s);
 }
@@ -658,7 +658,7 @@ string LFNIndex::lfn_generate_object_name(const ghobject_t &oid)
     t += snprintf(t, end - t, "snapdir");
   else
     t += snprintf(t, end - t, "%llx", (long long unsigned)oid.hobj.snap);
-  snprintf(t, end - t, "_%.*X", (int)(sizeof(oid.hobj.hash)*2), oid.hobj.hash);
+  snprintf(t, end - t, "_%.*X", (int)(sizeof(oid.hobj.get_hash())*2), oid.hobj.get_hash());
   full_name += string(buf);
   full_name.append("_");
 
@@ -722,7 +722,7 @@ string LFNIndex::lfn_generate_object_name_poolless(const ghobject_t &oid)
     t += snprintf(t, end - t, "snapdir");
   else
     t += snprintf(t, end - t, "%llx", (long long unsigned)oid.hobj.snap);
-  snprintf(t, end - t, "_%.*X", (int)(sizeof(oid.hobj.hash)*2), oid.hobj.hash);
+  snprintf(t, end - t, "_%.*X", (int)(sizeof(oid.hobj.get_hash())*2), oid.hobj.get_hash());
   full_name += string(snap_with_hash);
   return full_name;
 }
@@ -1010,7 +1010,10 @@ static int parse_object(const char *s, ghobject_t& o)
       o.hobj.snap = CEPH_SNAPDIR;
     else 
       o.hobj.snap = strtoull(bar+1, NULL, 16);
-    sscanf(hash, "_%X", &o.hobj.hash);
+      
+    uint32_t hobject_hash_input;
+    sscanf(hash, "_%X", &hobject_hash_input);
+    o.hobj.set_hash(hobject_hash_input);
 
     return 1;
   }
index b1f49c09cb13f15164021d55ce026be7b16c3fbf..2b981a3eaacf4af96549c087d7a4cfecd2630b30 100644 (file)
@@ -210,11 +210,11 @@ public:
     return false;
   }
   void insert(const hobject_t& o) {
-    hits.insert(o.hash);
+    hits.insert(o.get_hash());
     ++count;
   }
   bool contains(const hobject_t& o) const {
-    return hits.count(o.hash);
+    return hits.count(o.get_hash());
   }
   unsigned insert_count() const {
     return count;
@@ -431,10 +431,10 @@ public:
   }
 
   void insert(const hobject_t& o) {
-    bloom.insert(o.hash);
+    bloom.insert(o.get_hash());
   }
   bool contains(const hobject_t& o) const {
-    return bloom.contains(o.hash);
+    return bloom.contains(o.get_hash());
   }
   unsigned insert_count() const {
     return bloom.element_count();
index 586b6753380526efb0277721ae70ba5bbd3652a7..252b558a94b9ac654a1d0099804a17c67f41bb92 100644 (file)
@@ -60,7 +60,7 @@ void PGLog::IndexedLog::split_into(
   for (list<pg_log_entry_t>::iterator i = oldlog.begin();
        i != oldlog.end();
        ) {
-    if ((i->soid.hash & mask) == child_pgid.m_seed) {
+    if ((i->soid.get_hash() & mask) == child_pgid.m_seed) {
       olog->log.push_back(*i);
     } else {
       log.push_back(*i);
index 5f3a7117a8609aee5a720429fe4dc3f358969aff..9086136b27d84b56c14385b85016294cc181ccdd 100644 (file)
@@ -2567,7 +2567,7 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
 
   hobject_t snapoid(
     coid.oid, coid.get_key(),
-    obc->ssc->snapset.head_exists ? CEPH_NOSNAP:CEPH_SNAPDIR, coid.hash,
+    obc->ssc->snapset.head_exists ? CEPH_NOSNAP:CEPH_SNAPDIR, coid.get_hash(),
     info.pgid.pool(), coid.get_namespace());
   ObjectContextRef snapset_obc = get_object_context(snapoid, false);
 
@@ -3257,7 +3257,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
       MOSDOp *m = static_cast<MOSDOp *>(ctx->op->get_req());
       object_locator_t src_oloc;
       get_src_oloc(soid.oid, m->get_object_locator(), src_oloc);
-      hobject_t src_oid(osd_op.soid, src_oloc.key, soid.hash,
+      hobject_t src_oid(osd_op.soid, src_oloc.key, soid.get_hash(),
                        info.pgid.pool(), src_oloc.nspace);
       src_obc = ctx->src_obc[src_oid];
       dout(10) << " src_oid " << src_oid << " obc " << src_obc << dendl;
@@ -5040,7 +5040,7 @@ int ReplicatedPG::_rollback_to(OpContext *ctx, ceph_osd_op& op)
 
   ObjectContextRef rollback_to;
   int ret = find_object_context(
-    hobject_t(soid.oid, soid.get_key(), snapid, soid.hash, info.pgid.pool(),
+    hobject_t(soid.oid, soid.get_key(), snapid, soid.get_hash(), info.pgid.pool(),
              soid.get_namespace()),
     &rollback_to, false, false, &missing_oid);
   if (ret == -EAGAIN) {
@@ -5541,7 +5541,7 @@ void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc
     } else if (ctx->new_snapset.clones.size() &&
               !ctx->cache_evict) {
       // save snapset on _snap
-      hobject_t snapoid(soid.oid, soid.get_key(), CEPH_SNAPDIR, soid.hash,
+      hobject_t snapoid(soid.oid, soid.get_key(), CEPH_SNAPDIR, soid.get_hash(),
                        info.pgid.pool(), soid.get_namespace());
       dout(10) << " final snapset " << ctx->new_snapset
               << " in " << snapoid << dendl;
@@ -7585,9 +7585,9 @@ int ReplicatedPG::find_object_context(const hobject_t& oid,
                                      bool map_snapid_to_clone,
                                      hobject_t *pmissing)
 {
-  hobject_t head(oid.oid, oid.get_key(), CEPH_NOSNAP, oid.hash,
+  hobject_t head(oid.oid, oid.get_key(), CEPH_NOSNAP, oid.get_hash(),
                 info.pgid.pool(), oid.get_namespace());
-  hobject_t snapdir(oid.oid, oid.get_key(), CEPH_SNAPDIR, oid.hash,
+  hobject_t snapdir(oid.oid, oid.get_key(), CEPH_SNAPDIR, oid.get_hash(),
                    info.pgid.pool(), oid.get_namespace());
 
   // want the snapdir?
@@ -7750,7 +7750,7 @@ int ReplicatedPG::find_object_context(const hobject_t& oid,
     put_snapset_context(ssc);
     return -ENOENT;
   }
-  hobject_t soid(oid.oid, oid.get_key(), ssc->snapset.clones[k], oid.hash,
+  hobject_t soid(oid.oid, oid.get_key(), ssc->snapset.clones[k], oid.get_hash(),
                 info.pgid.pool(), oid.get_namespace());
 
   if (pg_log.get_missing().is_missing(soid)) {
@@ -11207,7 +11207,7 @@ void ReplicatedPG::hit_set_persist()
     assert(peer_info.count(*p));
     const pg_info_t& pi = peer_info[*p];
     if (pi.last_backfill == hobject_t() ||
-       pi.last_backfill.hash == info.pgid.ps()) {
+       pi.last_backfill.get_hash() == info.pgid.ps()) {
       dout(10) << __func__ << " backfill target osd." << *p
               << " last_backfill has not progressed past pgid ps"
               << dendl;
@@ -11408,9 +11408,9 @@ void ReplicatedPG::agent_setup()
     // choose random starting position
     agent_state->position = hobject_t();
     agent_state->position.pool = info.pgid.pool();
-    agent_state->position.hash = pool.info.get_random_pg_position(
+    agent_state->position.set_hash(pool.info.get_random_pg_position(
       info.pgid.pgid,
-      rand());
+      rand()));
     agent_state->start = agent_state->position;
 
     dout(10) << __func__ << " allocated new state, position "
index 8f1b9eae27d3a85eb31818a9ac29eb49cf9f92a7..e571c65a9e8b2cf6e33b6954e5291f848c93aedc 100644 (file)
@@ -3207,7 +3207,7 @@ void pg_missing_t::split_into(
   for (map<hobject_t, item>::iterator i = missing.begin();
        i != missing.end();
        ) {
-    if ((i->first.hash & mask) == child_pgid.m_seed) {
+    if ((i->first.get_hash() & mask) == child_pgid.m_seed) {
       omissing->add(i->first, i->second.need, i->second.have);
       rm(i++);
     } else {
@@ -4427,7 +4427,7 @@ void ScrubMap::dump(Formatter *f) const
   for (map<hobject_t,object>::const_iterator p = objects.begin(); p != objects.end(); ++p) {
     f->open_object_section("object");
     f->dump_string("name", p->first.oid.name);
-    f->dump_unsigned("hash", p->first.hash);
+    f->dump_unsigned("hash", p->first.get_hash());
     f->dump_string("key", p->first.get_key());
     f->dump_int("snapid", p->first.snap);
     p->second.dump(f);
index 49bf7583ae3f362e25675d1d8372f2cd66592390..de2ce47ea55444e67d43f24d55328dbf6c315a73 100644 (file)
@@ -1490,7 +1490,7 @@ void colsplittest(
   for (vector<ghobject_t>::iterator i = objects.begin();
        i != objects.end();
        ++i) {
-    ASSERT_EQ(!(i->hobj.hash & (1<<common_suffix_size)), 0u);
+    ASSERT_EQ(!(i->hobj.get_hash() & (1<<common_suffix_size)), 0u);
     t.remove(cid, *i);
   }
 
@@ -1501,7 +1501,7 @@ void colsplittest(
   for (vector<ghobject_t>::iterator i = objects.begin();
        i != objects.end();
        ++i) {
-    ASSERT_EQ(i->hobj.hash & (1<<common_suffix_size), 0u);
+    ASSERT_EQ(i->hobj.get_hash() & (1<<common_suffix_size), 0u);
     t.remove(tid, *i);
   }
 
@@ -1545,10 +1545,10 @@ TEST_P(StoreTest, TwoHash) {
     ObjectStore::Transaction t;
     ghobject_t o;
     if (i < 8) {
-      o.hobj.hash = (i << 16) | 0xA1;
+      o.hobj.set_hash((i << 16) | 0xA1);
       t.touch(cid, o);
     }
-    o.hobj.hash = (i << 16) | 0xB1;
+    o.hobj.set_hash((i << 16) | 0xB1);
     t.touch(cid, o);
     r = store->apply_transaction(t);
     ASSERT_EQ(r, 0);
@@ -1557,7 +1557,7 @@ TEST_P(StoreTest, TwoHash) {
   for (int i = 1; i < 8; ++i) {
     ObjectStore::Transaction t;
     ghobject_t o;
-    o.hobj.hash = (i << 16) | 0xA1;
+    o.hobj.set_hash((i << 16) | 0xA1);
     t.remove(cid, o);
     r = store->apply_transaction(t);
     ASSERT_EQ(r, 0);
@@ -1566,13 +1566,13 @@ TEST_P(StoreTest, TwoHash) {
   for (int i = 1; i < 8; ++i) {
     ObjectStore::Transaction t;
     ghobject_t o;
-    o.hobj.hash = (i << 16) | 0xA1;
+    o.hobj.set_hash((i << 16) | 0xA1);
     bool exists = store->exists(cid, o);
     ASSERT_EQ(exists, false);
   }
   {
     ghobject_t o;
-    o.hobj.hash = 0xA1;
+    o.hobj.set_hash(0xA1);
     bool exists = store->exists(cid, o);
     ASSERT_EQ(exists, true);
   }
@@ -1580,9 +1580,9 @@ TEST_P(StoreTest, TwoHash) {
   for (int i = 0; i < 360; ++i) {
     ObjectStore::Transaction t;
     ghobject_t o;
-    o.hobj.hash = (i << 16) | 0xA1;
+    o.hobj.set_hash((i << 16) | 0xA1);
     t.remove(cid, o);
-    o.hobj.hash = (i << 16) | 0xB1;
+    o.hobj.set_hash((i << 16) | 0xB1);
     t.remove(cid, o);
     r = store->apply_transaction(t);
     ASSERT_EQ(r, 0);
index 0d51ed9c2fb3328484d6093043ea930cdd5a3b1d..a940972fb2ae91e7675ffe76a79b67b291c1e80e 100644 (file)
@@ -39,7 +39,7 @@ public:
     stringstream ss;
     ss << "obj_" << id;
     hoid.oid = ss.str();
-    hoid.hash = id;
+    hoid.set_hash(id);
     return hoid;
   }
   static eversion_t mk_evt(unsigned ep, unsigned v) {
@@ -317,14 +317,14 @@ TEST_F(PGLogTest, rewind_divergent_log) {
     eversion_t newhead;
 
     hobject_t divergent;
-    divergent.hash = 0x9;
+    divergent.set_hash(0x9);
 
     {
       pg_log_entry_t e;
       e.mod_desc.mark_unrollbackable();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       log.tail = e.version;
       log.log.push_back(e);
       e.version = newhead = eversion_t(1, 4);
@@ -406,7 +406,7 @@ TEST_F(PGLogTest, rewind_divergent_log) {
       info.log_tail = log.tail = eversion_t(1, 1);
       newhead = eversion_t(1, 3);
       e.version = divergent_version = eversion_t(1, 5);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       divergent_object = e.soid;
       e.op = pg_log_entry_t::DELETE;
       e.prior_version = prior_version = eversion_t(0, 2);
@@ -449,8 +449,8 @@ TEST_F(PGLogTest, merge_old_entry) {
     list<hobject_t> remove_snap;
 
     info.last_backfill = hobject_t();
-    info.last_backfill.hash = 1;
-    oe.soid.hash = 2;
+    info.last_backfill.set_hash(1);
+    oe.soid.set_hash(2);
 
     EXPECT_FALSE(is_dirty());
     EXPECT_TRUE(remove_snap.empty());
@@ -651,7 +651,7 @@ TEST_F(PGLogTest, merge_old_entry) {
     list<hobject_t> remove_snap;
 
     info.log_tail = eversion_t(2,1);
-    oe.soid.hash = 1;
+    oe.soid.set_hash(1);
     oe.op = pg_log_entry_t::MODIFY;
     oe.prior_version = eversion_t(1,1);
 
@@ -689,7 +689,7 @@ TEST_F(PGLogTest, merge_old_entry) {
     list<hobject_t> remove_snap;
 
     info.log_tail = eversion_t(2,1);
-    oe.soid.hash = 1;
+    oe.soid.set_hash(1);
     oe.op = pg_log_entry_t::DELETE;
     oe.prior_version = eversion_t(1,1);
 
@@ -728,7 +728,7 @@ TEST_F(PGLogTest, merge_old_entry) {
     list<hobject_t> remove_snap;
 
     info.log_tail = eversion_t(10,1);
-    oe.soid.hash = 1;
+    oe.soid.set_hash(1);
     oe.op = pg_log_entry_t::MODIFY;
     oe.prior_version = eversion_t();
 
@@ -907,11 +907,11 @@ TEST_F(PGLogTest, merge_log) {
       e.mod_desc.mark_unrollbackable();
 
       e.version = eversion_t(1, 4);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       log.tail = e.version;
       log.log.push_back(e);
       e.version = eversion_t(1, 5);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       log.log.push_back(e);
       log.head = e.version;
       log.index();
@@ -919,11 +919,11 @@ TEST_F(PGLogTest, merge_log) {
       info.last_update = log.head;
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       olog.tail = e.version;
       olog.log.push_back(e);
       e.version = eversion_t(1, 5);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       olog.log.push_back(e);
       olog.head = e.version;
     }
@@ -1004,14 +1004,14 @@ TEST_F(PGLogTest, merge_log) {
       e.mod_desc.mark_unrollbackable();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       log.tail = e.version;
       log.log.push_back(e);
       e.version = eversion_t(1, 2);
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       log.log.push_back(e);
       e.version = eversion_t(1,3);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       divergent_object = e.soid;
       e.op = pg_log_entry_t::DELETE;
       log.log.push_back(e);
@@ -1021,18 +1021,18 @@ TEST_F(PGLogTest, merge_log) {
       info.last_update = log.head;
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       olog.tail = e.version;
       olog.log.push_back(e);
       e.version = eversion_t(1, 2);
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       olog.log.push_back(e);
       e.version = eversion_t(2, 3);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       e.op = pg_log_entry_t::MODIFY;
       olog.log.push_back(e);
       e.version = eversion_t(2, 4);
-      e.soid.hash = 0x7;
+      e.soid.set_hash(0x7);
       e.op = pg_log_entry_t::DELETE;
       olog.log.push_back(e);
       olog.head = e.version;
@@ -1070,7 +1070,7 @@ TEST_F(PGLogTest, merge_log) {
     /* DELETE entries from olog that are appended to the hed of the
        log are also added to remove_snap.
      */
-    EXPECT_EQ(0x7U, remove_snap.front().hash);
+    EXPECT_EQ(0x7U, remove_snap.front().get_hash());
     EXPECT_TRUE(t.empty());
     EXPECT_EQ(log.head, info.last_update);
     EXPECT_TRUE(info.purged_snaps.contains(purged_snap));
@@ -1117,14 +1117,14 @@ TEST_F(PGLogTest, merge_log) {
       e.mod_desc.mark_unrollbackable();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       log.tail = e.version;
       log.log.push_back(e);
       e.version = eversion_t(1, 4);
-      e.soid.hash = 0x7;
+      e.soid.set_hash(0x7);
       log.log.push_back(e);
       e.version = eversion_t(1, 5);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       log.log.push_back(e);
       log.head = e.version;
       log.index();
@@ -1132,11 +1132,11 @@ TEST_F(PGLogTest, merge_log) {
       info.last_update = log.head;
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       olog.tail = e.version;
       olog.log.push_back(e);
       e.version = eversion_t(1, 4);
-      e.soid.hash = 0x7;
+      e.soid.set_hash(0x7);
       olog.log.push_back(e);
       olog.head = e.version;
     }
@@ -1164,7 +1164,7 @@ TEST_F(PGLogTest, merge_log) {
     EXPECT_FALSE(missing.have_missing());
     EXPECT_EQ(2U, log.log.size());
     EXPECT_EQ(stat_version, info.stats.version);
-    EXPECT_EQ(0x9U, remove_snap.front().hash);
+    EXPECT_EQ(0x9U, remove_snap.front().get_hash());
     EXPECT_TRUE(t.empty());
     EXPECT_TRUE(info.purged_snaps.empty());
     EXPECT_TRUE(is_dirty());
@@ -1232,10 +1232,10 @@ TEST_F(PGLogTest, merge_log) {
 
       log.tail = eversion_t();
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       log.log.push_back(e);
       e.version = eversion_t(1, 2);
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       log.log.push_back(e);
       log.head = e.version;
       log.index();
@@ -1244,10 +1244,10 @@ TEST_F(PGLogTest, merge_log) {
 
       olog.tail = eversion_t(2, 3);
       e.version = eversion_t(2, 4);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       olog.log.push_back(e);
       e.version = eversion_t(2, 5);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       olog.log.push_back(e);
       olog.head = e.version;
     }
@@ -1326,22 +1326,22 @@ TEST_F(PGLogTest, proc_replica_log) {
       e.mod_desc.mark_unrollbackable();
 
       e.version = eversion_t(1, 2);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       log.tail = e.version;
       log.log.push_back(e);
       e.version = eversion_t(1, 3);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       e.op = pg_log_entry_t::DELETE;
       log.log.push_back(e);
       log.head = e.version;
       log.index();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       olog.tail = e.version;
       olog.log.push_back(e);
       e.version = eversion_t(2, 3);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       e.op = pg_log_entry_t::DELETE;
       olog.log.push_back(e);
       olog.head = e.version;
@@ -1378,7 +1378,7 @@ TEST_F(PGLogTest, proc_replica_log) {
 
       {
        e.soid = divergent_object;
-       e.soid.hash = 0x1;
+       e.soid.set_hash(0x1);
        e.version = eversion_t(1, 1);
        log.tail = e.version;
        log.log.push_back(e);
@@ -1389,24 +1389,24 @@ TEST_F(PGLogTest, proc_replica_log) {
        log.tail = e.version;
        log.log.push_back(e);
 
-       e.soid.hash = 0x3;
+       e.soid.set_hash(0x3);
        e.version = eversion_t(1, 4);
        log.log.push_back(e);
 
-       e.soid.hash = 0x7;
+       e.soid.set_hash(0x7);
        e.version = eversion_t(1, 5);
        log.log.push_back(e);
 
-       e.soid.hash = 0x8;
+       e.soid.set_hash(0x8);
        e.version = eversion_t(1, 6);
        log.log.push_back(e);
 
-       e.soid.hash = 0x9;
+       e.soid.set_hash(0x9);
        e.op = pg_log_entry_t::DELETE;
        e.version = eversion_t(2, 7);
        log.log.push_back(e);
 
-       e.soid.hash = 0xa;
+       e.soid.set_hash(0xa);
        e.version = eversion_t(2, 8);
        log.head = e.version;
        log.log.push_back(e);
@@ -1415,7 +1415,7 @@ TEST_F(PGLogTest, proc_replica_log) {
 
       {
        e.soid = divergent_object;
-       e.soid.hash = 0x1;
+       e.soid.set_hash(0x1);
        e.version = eversion_t(1, 1);
        olog.tail = e.version;
        olog.log.push_back(e);
@@ -1426,19 +1426,19 @@ TEST_F(PGLogTest, proc_replica_log) {
        olog.log.push_back(e);
 
        e.prior_version = eversion_t(0, 0);
-       e.soid.hash = 0x3;
+       e.soid.set_hash(0x3);
        e.version = eversion_t(1, 4);
        olog.log.push_back(e);
 
-       e.soid.hash = 0x7;
+       e.soid.set_hash(0x7);
        e.version = eversion_t(1, 5);
        olog.log.push_back(e);
 
-       e.soid.hash = 0x8;
+       e.soid.set_hash(0x8);
        e.version = eversion_t(1, 6);
        olog.log.push_back(e);
 
-       e.soid.hash = 0x9; // should not be added to missing, create
+       e.soid.set_hash(0x9); // should not be added to missing, create
        e.op = pg_log_entry_t::MODIFY;
        e.version = eversion_t(1, 7);
        olog.log.push_back(e);
@@ -1509,28 +1509,28 @@ TEST_F(PGLogTest, proc_replica_log) {
       e.mod_desc.mark_unrollbackable();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       log.tail = e.version;
       log.log.push_back(e);
       e.version = last_update;
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       log.log.push_back(e);
       e.version = eversion_t(1,3);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       e.op = pg_log_entry_t::DELETE;
       log.log.push_back(e);
       log.head = e.version;
       log.index();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       olog.tail = e.version;
       olog.log.push_back(e);
       e.version = last_update;
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       olog.log.push_back(e);
       e.version = eversion_t(2, 3);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       e.op = pg_log_entry_t::DELETE;
       olog.log.push_back(e);
       olog.head = e.version;
@@ -1593,28 +1593,28 @@ TEST_F(PGLogTest, proc_replica_log) {
       e.mod_desc.mark_unrollbackable();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       log.tail = e.version;
       log.log.push_back(e);
       e.version = last_update;
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       log.log.push_back(e);
       e.version = eversion_t(1, 3);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       e.op = pg_log_entry_t::DELETE;
       log.log.push_back(e);
       log.head = e.version;
       log.index();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x5;
+      e.soid.set_hash(0x5);
       olog.tail = e.version;
       olog.log.push_back(e);
       e.version = last_update;
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       olog.log.push_back(e);
       e.version = eversion_t(2, 3);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       divergent_object = e.soid;
       omissing.add(divergent_object, e.version, eversion_t());
       e.op = pg_log_entry_t::MODIFY;
@@ -1684,15 +1684,15 @@ TEST_F(PGLogTest, proc_replica_log) {
       e.mod_desc.mark_unrollbackable();
 
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       log.tail = e.version;
       log.log.push_back(e);
       e.version = last_update;
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       log.log.push_back(e);
       e.version = new_version;
       e.prior_version = eversion_t(1, 1);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       e.op = pg_log_entry_t::DELETE;
       log.log.push_back(e);
       log.head = e.version;
@@ -1700,15 +1700,15 @@ TEST_F(PGLogTest, proc_replica_log) {
 
       e.op = pg_log_entry_t::MODIFY;
       e.version = eversion_t(1, 1);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       olog.tail = e.version;
       olog.log.push_back(e);
       e.version = last_update;
-      e.soid.hash = 0x3;
+      e.soid.set_hash(0x3);
       olog.log.push_back(e);
       e.version = divergent_version;
       e.prior_version = eversion_t(1, 1);
-      e.soid.hash = 0x9;
+      e.soid.set_hash(0x9);
       divergent_object = e.soid;
       omissing.add(divergent_object, e.version, eversion_t());
       e.op = pg_log_entry_t::MODIFY;