summaryrefslogtreecommitdiffstats
path: root/storage/tokudb/PerconaFT/ftcxx/db.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/tokudb/PerconaFT/ftcxx/db.hpp')
-rw-r--r--storage/tokudb/PerconaFT/ftcxx/db.hpp370
1 files changed, 370 insertions, 0 deletions
diff --git a/storage/tokudb/PerconaFT/ftcxx/db.hpp b/storage/tokudb/PerconaFT/ftcxx/db.hpp
new file mode 100644
index 00000000..7f5af9b6
--- /dev/null
+++ b/storage/tokudb/PerconaFT/ftcxx/db.hpp
@@ -0,0 +1,370 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#ident "$Id$"
+/*======
+This file is part of PerconaFT.
+
+
+Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
+
+ PerconaFT is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2,
+ as published by the Free Software Foundation.
+
+ PerconaFT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
+
+----------------------------------------
+
+ PerconaFT is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License, version 3,
+ as published by the Free Software Foundation.
+
+ PerconaFT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
+======= */
+
+#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
+
+#pragma once
+
+#include <string>
+
+#include <db.h>
+
+#include "db_env.hpp"
+#include "db_txn.hpp"
+#include "exceptions.hpp"
+#include "slice.hpp"
+#include "stats.hpp"
+
+namespace ftcxx {
+
+ template<class Comparator, class Handler>
+ class CallbackCursor;
+ template<class Comparator, class Predicate>
+ class BufferedCursor;
+ template<class Comparator>
+ class SimpleCursor;
+
+ class DB {
+ public:
+ DB()
+ : _db(nullptr),
+ _close_on_destroy(false)
+ {}
+
+ explicit DB(::DB *d, bool close_on_destroy=false)
+ : _db(d),
+ _close_on_destroy(close_on_destroy)
+ {}
+
+ ~DB() {
+ if (_db && _close_on_destroy) {
+ close();
+ }
+ }
+
+ DB(const DB &) = delete;
+ DB& operator=(const DB &) = delete;
+
+ DB(DB &&o)
+ : _db(nullptr),
+ _close_on_destroy(false)
+ {
+ std::swap(_db, o._db);
+ std::swap(_close_on_destroy, o._close_on_destroy);
+ }
+
+ DB& operator=(DB &&o) {
+ std::swap(_db, o._db);
+ std::swap(_close_on_destroy, o._close_on_destroy);
+ return *this;
+ }
+
+ ::DB *db() const { return _db; }
+
+ Slice descriptor() const {
+ return Slice(_db->cmp_descriptor->dbt);
+ }
+
+ template<typename Callback>
+ int getf_set(const DBTxn &txn, const Slice &key, int flags, Callback cb) const {
+ class WrappedCallback {
+ Callback &_cb;
+ public:
+ WrappedCallback(Callback &cb_)
+ : _cb(cb_)
+ {}
+
+ static int call(const DBT *key_, const DBT *val_, void *extra) {
+ WrappedCallback *wc = static_cast<WrappedCallback *>(extra);
+ return wc->call(key_, val_);
+ }
+
+ int call(const DBT *key_, const DBT *val_) {
+ return _cb(Slice(*key_), Slice(*val_));
+ }
+ } wc(cb);
+
+ DBT kdbt = key.dbt();
+ return _db->getf_set(_db, txn.txn(), flags, &kdbt, &WrappedCallback::call, &wc);
+ }
+
+ int put(const DBTxn &txn, DBT *key, DBT *val, int flags=0) const {
+ return _db->put(_db, txn.txn(), key, val, flags);
+ }
+
+ int put(const DBTxn &txn, const Slice &key, const Slice &val, int flags=0) const {
+ DBT kdbt = key.dbt();
+ DBT vdbt = val.dbt();
+ return put(txn, &kdbt, &vdbt, flags);
+ }
+
+ int update(const DBTxn &txn, DBT *key, DBT *val, int flags=0) const {
+ return _db->update(_db, txn.txn(), key, val, flags);
+ }
+
+ int update(const DBTxn &txn, const Slice &key, const Slice &extra, int flags=0) const {
+ DBT kdbt = key.dbt();
+ DBT edbt = extra.dbt();
+ return update(txn, &kdbt, &edbt, flags);
+ }
+
+ int del(const DBTxn &txn, DBT *key, int flags=0) const {
+ return _db->del(_db, txn.txn(), key, flags);
+ }
+
+ int del(const DBTxn &txn, const Slice &key, int flags=0) const {
+ DBT kdbt = key.dbt();
+ return _db->del(_db, txn.txn(), &kdbt, flags);
+ }
+
+ template<class OptimizeCallback>
+ int hot_optimize(const Slice &left, const Slice &right, OptimizeCallback callback, uint64_t *loops_run = NULL) const {
+ DBT ldbt = left.dbt();
+ DBT rdbt = right.dbt();
+
+ class WrappedOptimizeCallback {
+ OptimizeCallback &_oc;
+ size_t _loops;
+
+ public:
+ WrappedOptimizeCallback(OptimizeCallback &oc)
+ : _oc(oc),
+ _loops(0)
+ {}
+
+ static int call(void *extra, float progress) {
+ WrappedOptimizeCallback *e = static_cast<WrappedOptimizeCallback *>(extra);
+ return e->_oc(progress, ++e->_loops);
+ }
+ } woc(callback);
+
+ uint64_t dummy;
+ return _db->hot_optimize(_db, &ldbt, &rdbt,
+ &WrappedOptimizeCallback::call, &woc,
+ loops_run == NULL ? &dummy : loops_run);
+ }
+
+ Stats get_stats() const {
+ Stats stats;
+ DB_BTREE_STAT64 s = {0, 0, 0, 0, 0, 0, 0};
+ int r = _db->stat64(_db, NULL, &s);
+ handle_ft_retval(r);
+ stats.data_size = s.bt_dsize;
+ stats.file_size = s.bt_fsize;
+ stats.num_keys = s.bt_nkeys;
+ return stats;
+ }
+
+ struct NullFilter {
+ bool operator()(const Slice &, const Slice &) {
+ return true;
+ }
+ };
+
+ /**
+ * Constructs a Cursor over this DB, over the range from left to
+ * right (or right to left if !forward).
+ */
+ template<class Comparator, class Handler>
+ CallbackCursor<Comparator, Handler> cursor(const DBTxn &txn, DBT *left, DBT *right,
+ Comparator &&cmp, Handler &&handler, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator, class Handler>
+ CallbackCursor<Comparator, Handler> cursor(const DBTxn &txn, const Slice &start_key,
+ Comparator &&cmp, Handler &&handler, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator, class Handler>
+ CallbackCursor<Comparator, Handler> cursor(const DBTxn &txn, const Slice &left, const Slice &right,
+ Comparator &&cmp, Handler &&handler, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator, class Handler>
+ CallbackCursor<Comparator, Handler> cursor(const DBTxn &txn, Comparator &&cmp, Handler &&handler,
+ int flags=0, bool forward=true, bool prelock=false) const;
+
+ template<class Comparator, class Predicate>
+ BufferedCursor<Comparator, Predicate> buffered_cursor(const DBTxn &txn, DBT *left, DBT *right,
+ Comparator &&cmp, Predicate &&filter, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator, class Predicate>
+ BufferedCursor<Comparator, Predicate> buffered_cursor(const DBTxn &txn, const Slice &start_key,
+ Comparator &&cmp, Predicate &&filter, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator, class Predicate>
+ BufferedCursor<Comparator, Predicate> buffered_cursor(const DBTxn &txn, const Slice &left, const Slice &right,
+ Comparator &&cmp, Predicate &&filter, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator, class Predicate>
+ BufferedCursor<Comparator, Predicate> buffered_cursor(const DBTxn &txn, Comparator &&cmp, Predicate &&filter,
+ int flags=0, bool forward=true, bool prelock=false) const;
+
+ template<class Comparator>
+ SimpleCursor<Comparator> simple_cursor(const DBTxn &txn, DBT *left, DBT *right,
+ Comparator &&cmp, Slice &key, Slice &val, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator>
+ SimpleCursor<Comparator> simple_cursor(const DBTxn &txn, const Slice &start_key,
+ Comparator &&cmp, Slice &key, Slice &val, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator>
+ SimpleCursor<Comparator> simple_cursor(const DBTxn &txn, const Slice &left, const Slice &right,
+ Comparator &&cmp, Slice &key, Slice &val, int flags=0,
+ bool forward=true, bool end_exclusive=false, bool prelock=false) const;
+
+ template<class Comparator>
+ SimpleCursor<Comparator> simple_cursor(const DBTxn &txn, Comparator &&cmp, Slice &key, Slice &val,
+ int flags=0, bool forward=true, bool prelock=false) const;
+
+ void close() {
+ int r = _db->close(_db, 0);
+ handle_ft_retval(r);
+ _db = nullptr;
+ }
+
+ private:
+ ::DB *_db;
+ bool _close_on_destroy;
+ };
+
+ class DBBuilder {
+ uint32_t _readpagesize;
+ int _compression_method;
+ uint32_t _fanout;
+ uint8_t _memcmp_magic;
+ uint32_t _pagesize;
+ Slice _descriptor;
+
+ public:
+ DBBuilder()
+ : _readpagesize(0),
+ _compression_method(-1),
+ _fanout(0),
+ _memcmp_magic(0),
+ _pagesize(0),
+ _descriptor()
+ {}
+
+ DB open(const DBEnv &env, const DBTxn &txn, const char *fname, const char *dbname, DBTYPE dbtype, uint32_t flags, int mode) const {
+ ::DB *db;
+ int r = db_create(&db, env.env(), 0);
+ handle_ft_retval(r);
+
+ if (_readpagesize) {
+ r = db->set_readpagesize(db, _readpagesize);
+ handle_ft_retval(r);
+ }
+
+ if (_compression_method >= 0) {
+ r = db->set_compression_method(db, TOKU_COMPRESSION_METHOD(_compression_method));
+ handle_ft_retval(r);
+ }
+
+ if (_fanout) {
+ r = db->set_fanout(db, _fanout);
+ handle_ft_retval(r);
+ }
+
+ if (_memcmp_magic) {
+ r = db->set_memcmp_magic(db, _memcmp_magic);
+ handle_ft_retval(r);
+ }
+
+ if (_pagesize) {
+ r = db->set_pagesize(db, _pagesize);
+ handle_ft_retval(r);
+ }
+
+ const DBTxn *txnp = &txn;
+ DBTxn writeTxn;
+ if (txn.is_read_only()) {
+ writeTxn = DBTxn(env, DB_SERIALIZABLE);
+ txnp = &writeTxn;
+ }
+
+ r = db->open(db, txnp->txn(), fname, dbname, dbtype, flags, mode);
+ handle_ft_retval(r);
+
+ if (!_descriptor.empty()) {
+ DBT desc = _descriptor.dbt();
+ r = db->change_descriptor(db, txnp->txn(), &desc, DB_UPDATE_CMP_DESCRIPTOR);
+ handle_ft_retval(r);
+ }
+
+ if (txn.is_read_only()) {
+ writeTxn.commit();
+ }
+
+ return DB(db, true);
+ }
+
+ DBBuilder& set_readpagesize(uint32_t readpagesize) {
+ _readpagesize = readpagesize;
+ return *this;
+ }
+
+ DBBuilder& set_compression_method(TOKU_COMPRESSION_METHOD _compressionmethod) {
+ _compression_method = int(_compressionmethod);
+ return *this;
+ }
+
+ DBBuilder& set_fanout(uint32_t fanout) {
+ _fanout = fanout;
+ return *this;
+ }
+
+ DBBuilder& set_memcmp_magic(uint8_t _memcmpmagic) {
+ _memcmp_magic = _memcmpmagic;
+ return *this;
+ }
+
+ DBBuilder& set_pagesize(uint32_t pagesize) {
+ _pagesize = pagesize;
+ return *this;
+ }
+
+ DBBuilder& set_descriptor(const Slice &desc) {
+ _descriptor = desc.owned();
+ return *this;
+ }
+ };
+
+} // namespace ftcxx