cid(cid),
lock("BlueStore::Collection::lock", true, false),
exists(true),
- // size the shared blob hash table as a ratio of the onode cache size.
- shared_blob_set(MAX(16,
- g_conf->bluestore_onode_cache_size /
- store->cache_shards.size() *
- g_conf->bluestore_shared_blob_hash_table_size_ratio)),
onode_map(c)
{
}
struct SharedBlobSet;
/// in-memory shared blob state (incl cached buffers)
- struct SharedBlob : public boost::intrusive::unordered_set_base_hook<> {
+ struct SharedBlob {
std::atomic_int nref = {0}; ///< reference count
// these are defined/set if the shared_blob is 'loaded'
/// a lookup table of SharedBlobs
struct SharedBlobSet {
- typedef boost::intrusive::unordered_set<SharedBlob>::bucket_type bucket_type;
- typedef boost::intrusive::unordered_set<SharedBlob>::bucket_traits bucket_traits;
-
std::mutex lock; ///< protect lookup, insertion, removal
- int num_buckets;
- vector<bucket_type> buckets;
- boost::intrusive::unordered_set<SharedBlob> uset;
-
- SharedBlob dummy; ///< for lookups
- explicit SharedBlobSet(unsigned n)
- : num_buckets(n),
- buckets(n),
- uset(bucket_traits(buckets.data(), num_buckets)),
- dummy(0, string(), nullptr) {
- assert(n > 0);
- }
+ // we use a bare pointer because we don't want to affect the ref
+ // count
+ std::unordered_map<uint64_t,SharedBlob*> sb_map;
SharedBlobRef lookup(uint64_t sbid) {
std::lock_guard<std::mutex> l(lock);
- dummy.sbid = sbid;
- auto p = uset.find(dummy);
- if (p == uset.end()) {
+ auto p = sb_map.find(sbid);
+ if (p == sb_map.end()) {
return nullptr;
}
- return &*p;
+ return p->second;
}
void add(SharedBlob *sb) {
std::lock_guard<std::mutex> l(lock);
- uset.insert(*sb);
+ sb_map[sb->sbid] = sb;
sb->parent_set = this;
}
std::lock_guard<std::mutex> l(lock);
if (sb->nref == 0) {
assert(sb->parent_set == this);
- uset.erase(*sb);
+ sb_map.erase(sb->sbid);
return true;
}
return false;
bool empty() {
std::lock_guard<std::mutex> l(lock);
- return uset.empty();
+ return sb_map.empty();
}
};
P(std::atomic_int);
P(BlueStore::SharedBlobRef);
P(boost::intrusive::set_base_hook<>);
+ P(boost::intrusive::unordered_set_base_hook<>);
P(bufferlist);
cout << "map<uint64_t,uint64_t>\t" << sizeof(map<uint64_t,uint64_t>) << std::endl;
cout << "map<char,char>\t" << sizeof(map<char,char>) << std::endl;