summaryrefslogtreecommitdiff
path: root/leveldb/0003-allow-Get-calls-to-avoid-copies-into-std-string.patch
blob: 498f81e3c563c3113e42be579ec17637fb584834 (plain)
    1 From: Steve Vinoski <vinoski@ieee.org>
    2 Date: Thu, 20 Dec 2012 16:14:11 -0500
    3 Subject: [PATCH] allow Get() calls to avoid copies into std::string
    4 
    5 Add a new abstract base class leveldb::Value that applications can easily
    6 derive from to supply their own memory management for values retrieved via
    7 Get(). Add an internal class derived from Value that provides std::string
    8 management to preserve backward compatibility. Overload DBImpl::Get() to
    9 accept a Value*, and to preserve backward compatibility also keep the
   10 original version taking a std::string*.
   11 
   12 diff --git a/db/db_impl.cc b/db/db_impl.cc
   13 index ae7b96d..5c3a05c 100644
   14 --- a/db/db_impl.cc
   15 +++ b/db/db_impl.cc
   16 @@ -85,6 +85,22 @@ struct DBImpl::CompactionState {
   17    uint64_t total_bytes;
   18  };
   19  
   20 +Value::~Value() {}
   21 +
   22 +class StringValue : public Value {
   23 + public:
   24 +  explicit StringValue(std::string& val) : value_(val) {}
   25 +  ~StringValue() {}
   26 +
   27 +  StringValue& assign(const char* data, size_t size) {
   28 +    value_.assign(data, size);
   29 +    return *this;
   30 +  }
   31 +
   32 + private:
   33 +  std::string& value_;
   34 +};
   35 +
   36  // Fix user-supplied options to be reasonable
   37  template <class T, class V>
   38  static void ClipToRange(T* ptr, V minvalue, V maxvalue) {
   39 @@ -1117,6 +1133,13 @@ int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes() {
   40  
   41  Status DBImpl::Get(const ReadOptions& options, const Slice& key,
   42                     std::string* value) {
   43 +  StringValue stringvalue(*value);
   44 +  return DBImpl::Get(options, key, &stringvalue);
   45 +}
   46 +
   47 +Status DBImpl::Get(const ReadOptions& options,
   48 +                   const Slice& key,
   49 +                   Value* value) {
   50    Status s;
   51    MutexLock l(&mutex_);
   52    SequenceNumber snapshot;
   53 diff --git a/db/db_impl.h b/db/db_impl.h
   54 index d955c2a..3127110 100644
   55 --- a/db/db_impl.h
   56 +++ b/db/db_impl.h
   57 @@ -42,6 +42,9 @@ class DBImpl : public DB {
   58    Status Write(const WriteOptions& options, WriteBatch* updates) override;
   59    Status Get(const ReadOptions& options, const Slice& key,
   60               std::string* value) override;
   61 +  virtual Status Get(const ReadOptions& options,
   62 +	              const Slice& key,
   63 +	              Value* value);
   64    Iterator* NewIterator(const ReadOptions&) override;
   65    const Snapshot* GetSnapshot() override;
   66    void ReleaseSnapshot(const Snapshot* snapshot) override;
   67 diff --git a/db/db_test.cc b/db/db_test.cc
   68 index 2e65370..db778d9 100644
   69 --- a/db/db_test.cc
   70 +++ b/db/db_test.cc
   71 @@ -2065,6 +2065,11 @@ class ModelDB : public DB {
   72      assert(false);  // Not implemented
   73      return Status::NotFound(key);
   74    }
   75 +  Status Get(const ReadOptions& options,
   76 +	     const Slice& key, Value* value) override {
   77 +    assert(false);      // Not implemented
   78 +    return Status::NotFound(key);
   79 +  }
   80    Iterator* NewIterator(const ReadOptions& options) override {
   81      if (options.snapshot == nullptr) {
   82        KVMap* saved = new KVMap;
   83 diff --git a/db/memtable.cc b/db/memtable.cc
   84 index f42774d..4689e2d 100644
   85 --- a/db/memtable.cc
   86 +++ b/db/memtable.cc
   87 @@ -98,7 +98,7 @@ void MemTable::Add(SequenceNumber s, ValueType type, const Slice& key,
   88    table_.Insert(buf);
   89  }
   90  
   91 -bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {
   92 +bool MemTable::Get(const LookupKey& key, Value* value, Status* s) {
   93    Slice memkey = key.memtable_key();
   94    Table::Iterator iter(&table_);
   95    iter.Seek(memkey.data());
   96 diff --git a/db/memtable.h b/db/memtable.h
   97 index 9d986b1..85c4cce 100644
   98 --- a/db/memtable.h
   99 +++ b/db/memtable.h
  100 @@ -60,7 +60,7 @@ class MemTable {
  101    // If memtable contains a deletion for key, store a NotFound() error
  102    // in *status and return true.
  103    // Else, return false.
  104 -  bool Get(const LookupKey& key, std::string* value, Status* s);
  105 +  bool Get(const LookupKey& key, Value* value, Status* s);
  106  
  107   private:
  108    friend class MemTableIterator;
  109 diff --git a/db/version_set.cc b/db/version_set.cc
  110 index 1963353..c83a4d2 100644
  111 --- a/db/version_set.cc
  112 +++ b/db/version_set.cc
  113 @@ -256,7 +256,7 @@ struct Saver {
  114    SaverState state;
  115    const Comparator* ucmp;
  116    Slice user_key;
  117 -  std::string* value;
  118 +  Value* value;
  119  };
  120  }  // namespace
  121  static void SaveValue(void* arg, const Slice& ikey, const Slice& v) {
  122 @@ -322,7 +322,7 @@ void Version::ForEachOverlapping(Slice user_key, Slice internal_key, void* arg,
  123  }
  124  
  125  Status Version::Get(const ReadOptions& options, const LookupKey& k,
  126 -                    std::string* value, GetStats* stats) {
  127 +                    Value* value, GetStats* stats) {
  128    stats->seek_file = nullptr;
  129    stats->seek_file_level = -1;
  130  
  131 diff --git a/db/version_set.h b/db/version_set.h
  132 index 69f3d70..0f0a463 100644
  133 --- a/db/version_set.h
  134 +++ b/db/version_set.h
  135 @@ -72,7 +72,7 @@ class Version {
  136    // REQUIRES: This version has been saved (see VersionSet::SaveTo)
  137    void AddIterators(const ReadOptions&, std::vector<Iterator*>* iters);
  138  
  139 -  Status Get(const ReadOptions&, const LookupKey& key, std::string* val,
  140 +  Status Get(const ReadOptions&, const LookupKey& key, Value* val,
  141               GetStats* stats);
  142  
  143    // Adds "stats" into the current state.  Returns true if a new
  144 diff --git a/include/leveldb/db.h b/include/leveldb/db.h
  145 index 61c29c0..1a93feb 100644
  146 --- a/include/leveldb/db.h
  147 +++ b/include/leveldb/db.h
  148 @@ -40,6 +40,17 @@ struct LEVELDB_EXPORT Range {
  149    Slice limit;  // Not included in the range
  150  };
  151  
  152 +// Abstract holder for a DB value.
  153 +// This allows callers to manage their own value buffers and have
  154 +// DB values copied directly into those buffers.
  155 +class Value {
  156 + public:
  157 +  virtual Value& assign(const char* data, size_t size) = 0;
  158 +
  159 + protected:
  160 +  virtual ~Value();
  161 +};
  162 +
  163  // A DB is a persistent ordered map from keys to values.
  164  // A DB is safe for concurrent access from multiple threads without
  165  // any external synchronization.

Generated by cgit