Summary: I created a separate class ColumnFamilySet to keep track of column families. Before we did this in VersionSet and I believe this approach is cleaner. Let me know if you have any comments. I will commit tomorrow. Test Plan: make check Reviewers: dhruba, haobo, kailiu, sdong CC: leveldb Differential Revision: https://reviews.facebook.net/D15357main
parent
f9a25dda9f
commit
7c5e583a27
@ -0,0 +1,86 @@ |
||||
#include "db/column_family.h" |
||||
#include "db/version_set.h" |
||||
|
||||
namespace rocksdb { |
||||
|
||||
ColumnFamilyData::ColumnFamilyData(uint32_t id, const std::string& name, |
||||
Version* dummy_versions, |
||||
const ColumnFamilyOptions& options) |
||||
: id(id), |
||||
name(name), |
||||
dummy_versions(dummy_versions), |
||||
current(nullptr), |
||||
options(options) {} |
||||
|
||||
ColumnFamilyData::~ColumnFamilyData() { |
||||
// List must be empty
|
||||
assert(dummy_versions->next_ == dummy_versions); |
||||
delete dummy_versions; |
||||
} |
||||
|
||||
ColumnFamilySet::ColumnFamilySet() : max_column_family_(0) {} |
||||
|
||||
ColumnFamilySet::~ColumnFamilySet() { |
||||
for (auto& cfd : column_family_data_) { |
||||
delete cfd.second; |
||||
} |
||||
for (auto& cfd : droppped_column_families_) { |
||||
delete cfd; |
||||
} |
||||
} |
||||
|
||||
ColumnFamilyData* ColumnFamilySet::GetDefault() const { |
||||
auto ret = GetColumnFamily(0); |
||||
assert(ret != nullptr); // default column family should always exist
|
||||
return ret; |
||||
} |
||||
|
||||
ColumnFamilyData* ColumnFamilySet::GetColumnFamily(uint32_t id) const { |
||||
auto cfd_iter = column_family_data_.find(id); |
||||
if (cfd_iter != column_family_data_.end()) { |
||||
return cfd_iter->second; |
||||
} else { |
||||
return nullptr; |
||||
} |
||||
} |
||||
|
||||
bool ColumnFamilySet::Exists(uint32_t id) { |
||||
return column_family_data_.find(id) != column_family_data_.end(); |
||||
} |
||||
|
||||
bool ColumnFamilySet::Exists(const std::string& name) { |
||||
return column_families_.find(name) != column_families_.end(); |
||||
} |
||||
|
||||
uint32_t ColumnFamilySet::GetID(const std::string& name) { |
||||
auto cfd_iter = column_families_.find(name); |
||||
assert(cfd_iter != column_families_.end()); |
||||
return cfd_iter->second; |
||||
} |
||||
|
||||
uint32_t ColumnFamilySet::GetNextColumnFamilyID() { |
||||
return ++max_column_family_; |
||||
} |
||||
|
||||
ColumnFamilyData* ColumnFamilySet::CreateColumnFamily( |
||||
const std::string& name, uint32_t id, Version* dummy_versions, |
||||
const ColumnFamilyOptions& options) { |
||||
assert(column_families_.find(name) == column_families_.end()); |
||||
column_families_.insert({name, id}); |
||||
ColumnFamilyData* new_cfd = |
||||
new ColumnFamilyData(id, name, dummy_versions, options); |
||||
column_family_data_.insert({id, new_cfd}); |
||||
max_column_family_ = std::max(max_column_family_, id); |
||||
return new_cfd; |
||||
} |
||||
|
||||
void ColumnFamilySet::DropColumnFamily(uint32_t id) { |
||||
auto cfd = column_family_data_.find(id); |
||||
assert(cfd != column_family_data_.end()); |
||||
column_families_.erase(cfd->second->name); |
||||
cfd->second->current->Unref(); |
||||
droppped_column_families_.push_back(cfd->second); |
||||
column_family_data_.erase(cfd); |
||||
} |
||||
|
||||
} // namespace rocksdb
|
@ -0,0 +1,87 @@ |
||||
// Copyright (c) 2013, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||
|
||||
#pragma once |
||||
|
||||
#include "rocksdb/options.h" |
||||
|
||||
#include <map> |
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
namespace rocksdb { |
||||
|
||||
class Version; |
||||
class VersionSet; |
||||
|
||||
// column family metadata
|
||||
struct ColumnFamilyData { |
||||
uint32_t id; |
||||
std::string name; |
||||
Version* dummy_versions; // Head of circular doubly-linked list of versions.
|
||||
Version* current; // == dummy_versions->prev_
|
||||
ColumnFamilyOptions options; |
||||
|
||||
ColumnFamilyData(uint32_t id, const std::string& name, |
||||
Version* dummy_versions, const ColumnFamilyOptions& options); |
||||
~ColumnFamilyData(); |
||||
}; |
||||
|
||||
class ColumnFamilySet { |
||||
public: |
||||
class iterator { |
||||
public: |
||||
explicit iterator( |
||||
std::unordered_map<uint32_t, ColumnFamilyData*>::iterator itr) |
||||
: itr_(itr) {} |
||||
iterator& operator++() { |
||||
++itr_; |
||||
return *this; |
||||
} |
||||
bool operator!=(const iterator& other) { return this->itr_ != other.itr_; } |
||||
ColumnFamilyData* operator*() { return itr_->second; } |
||||
private: |
||||
std::unordered_map<uint32_t, ColumnFamilyData*>::iterator itr_; |
||||
}; |
||||
|
||||
ColumnFamilySet(); |
||||
~ColumnFamilySet(); |
||||
|
||||
ColumnFamilyData* GetDefault() const; |
||||
// GetColumnFamily() calls return nullptr if column family is not found
|
||||
ColumnFamilyData* GetColumnFamily(uint32_t id) const; |
||||
bool Exists(uint32_t id); |
||||
bool Exists(const std::string& name); |
||||
uint32_t GetID(const std::string& name); |
||||
// this call will return the next available column family ID. it guarantees
|
||||
// that there is no column family with id greater than or equal to the
|
||||
// returned value in the current running instance. It does not, however,
|
||||
// guarantee that the returned ID is unique accross RocksDB restarts.
|
||||
// For example, if a client adds a column family 6 and then drops it,
|
||||
// after a restart, we might reuse column family 6 ID.
|
||||
uint32_t GetNextColumnFamilyID(); |
||||
|
||||
ColumnFamilyData* CreateColumnFamily(const std::string& name, uint32_t id, |
||||
Version* dummy_version, |
||||
const ColumnFamilyOptions& options); |
||||
void DropColumnFamily(uint32_t id); |
||||
|
||||
iterator begin() { return iterator(column_family_data_.begin()); } |
||||
iterator end() { return iterator(column_family_data_.end()); } |
||||
|
||||
private: |
||||
std::unordered_map<std::string, uint32_t> column_families_; |
||||
std::unordered_map<uint32_t, ColumnFamilyData*> column_family_data_; |
||||
// we need to keep them alive because we still can't control the lifetime of
|
||||
// all of column family data members (options for example)
|
||||
std::vector<ColumnFamilyData*> droppped_column_families_; |
||||
uint32_t max_column_family_; |
||||
}; |
||||
|
||||
} // namespace rocksdb
|
Loading…
Reference in new issue