summaryrefslogtreecommitdiff
path: root/src/os/KeyValueDB.h
blob: f62bca996a57c0ed0e110b8f0c4ce30c6a32da20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef KEY_VALUE_DB_H
#define KEY_VALUE_DB_H

#include "include/buffer.h"
#include <set>
#include <map>
#include <string>
#include <tr1/memory>
#include <boost/scoped_ptr.hpp>
#include "ObjectMap.h"

using std::string;
/**
 * Defines virtual interface to be implemented by key value store
 *
 * Kyoto Cabinet or LevelDB should implement this
 */
class KeyValueDB {
public:
  class TransactionImpl {
  public:
    /// Set Keys
    void set(
      const string &prefix,                 ///< [in] Prefix for keys
      const std::map<string, bufferlist> &to_set ///< [in] keys/values to set
    ) {
      std::map<string, bufferlist>::const_iterator it;
      for (it = to_set.begin(); it != to_set.end(); ++it)
	set(prefix, it->first, it->second);
    }

    /// Set Key
    virtual void set(
      const string &prefix,   ///< [in] Prefix for the key
      const string &k,	      ///< [in] Key to set
      const bufferlist &bl    ///< [in] Value to set
      ) = 0;


    /// Removes Keys
    void rmkeys(
      const string &prefix,   ///< [in] Prefix to search for
      const std::set<string> &keys ///< [in] Keys to remove
    ) {
      std::set<string>::const_iterator it;
      for (it = keys.begin(); it != keys.end(); ++it)
	rmkey(prefix, *it);
    }

    /// Remove Key
    virtual void rmkey(
      const string &prefix,   ///< [in] Prefix to search for
      const string &k	      ///< [in] Key to remove
      ) = 0;

    /// Removes keys beginning with prefix
    virtual void rmkeys_by_prefix(
      const string &prefix ///< [in] Prefix by which to remove keys
      ) = 0;

    virtual ~TransactionImpl() {};
  };
  typedef std::tr1::shared_ptr< TransactionImpl > Transaction;

  virtual Transaction get_transaction() = 0;
  virtual int submit_transaction(Transaction) = 0;
  virtual int submit_transaction_sync(Transaction t) {
    return submit_transaction(t);
  }

  /// Retrieve Keys
  virtual int get(
    const string &prefix,        ///< [in] Prefix for key
    const std::set<string> &key,      ///< [in] Key to retrieve
    std::map<string, bufferlist> *out ///< [out] Key value retrieved
    ) = 0;

  class WholeSpaceIteratorImpl {
  public:
    virtual int seek_to_first() = 0;
    virtual int seek_to_first(const string &prefix) = 0;
    virtual int seek_to_last() = 0;
    virtual int seek_to_last(const string &prefix) = 0;
    virtual int upper_bound(const string &prefix, const string &after) = 0;
    virtual int lower_bound(const string &prefix, const string &to) = 0;
    virtual bool valid() = 0;
    virtual int next() = 0;
    virtual int prev() = 0;
    virtual string key() = 0;
    virtual pair<string,string> raw_key() = 0;
    virtual bufferlist value() = 0;
    virtual int status() = 0;
    virtual ~WholeSpaceIteratorImpl() { }
  };
  typedef std::tr1::shared_ptr< WholeSpaceIteratorImpl > WholeSpaceIterator;

  class IteratorImpl : public ObjectMap::ObjectMapIteratorImpl {
    const string prefix;
    WholeSpaceIterator generic_iter;
  public:
    IteratorImpl(const string &prefix, WholeSpaceIterator iter) :
      prefix(prefix), generic_iter(iter) { }
    virtual ~IteratorImpl() { }

    int seek_to_first() {
      return generic_iter->seek_to_first(prefix);
    }
    int seek_to_last() {
      return generic_iter->seek_to_last(prefix);
    }
    int upper_bound(const string &after) {
      return generic_iter->upper_bound(prefix, after);
    }
    int lower_bound(const string &to) {
      return generic_iter->lower_bound(prefix, to);
    }
    bool valid() {
      if (!generic_iter->valid())
	return false;
      pair<string,string> raw_key = generic_iter->raw_key();
      return (raw_key.first == prefix);
    }
    int next() {
      if (valid())
	return generic_iter->next();
      return status();
    }
    int prev() {
      if (valid())
	return generic_iter->prev();
      return status();
    }
    string key() {
      return generic_iter->key();
    }
    bufferlist value() {
      return generic_iter->value();
    }
    int status() {
      return generic_iter->status();
    }
  };

  typedef std::tr1::shared_ptr< IteratorImpl > Iterator;

  WholeSpaceIterator get_iterator() {
    return _get_iterator();
  }

  Iterator get_iterator(const string &prefix) {
    return std::tr1::shared_ptr<IteratorImpl>(
      new IteratorImpl(prefix, get_iterator())
    );
  }

  WholeSpaceIterator get_snapshot_iterator() {
    return _get_snapshot_iterator();
  }

  Iterator get_snapshot_iterator(const string &prefix) {
    return std::tr1::shared_ptr<IteratorImpl>(
      new IteratorImpl(prefix, get_snapshot_iterator())
    );
  }

  virtual ~KeyValueDB() {}

protected:
  virtual WholeSpaceIterator _get_iterator() = 0;
  virtual WholeSpaceIterator _get_snapshot_iterator() = 0;
};

#endif