summaryrefslogtreecommitdiffstats
path: root/storage/tokudb/PerconaFT/ft/comparator.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/tokudb/PerconaFT/ft/comparator.h')
-rw-r--r--storage/tokudb/PerconaFT/ft/comparator.h150
1 files changed, 150 insertions, 0 deletions
diff --git a/storage/tokudb/PerconaFT/ft/comparator.h b/storage/tokudb/PerconaFT/ft/comparator.h
new file mode 100644
index 00000000..dfafd715
--- /dev/null
+++ b/storage/tokudb/PerconaFT/ft/comparator.h
@@ -0,0 +1,150 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+/*======
+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/>.
+
+----------------------------------------
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+======= */
+
+#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
+
+#pragma once
+
+#include <db.h>
+#include <string.h>
+
+#include "portability/memory.h"
+
+#include "util/dbt.h"
+
+typedef int (*ft_compare_func)(DB *db, const DBT *a, const DBT *b);
+
+int toku_keycompare(const void *key1, uint32_t key1len, const void *key2, uint32_t key2len);
+
+int toku_builtin_compare_fun (DB *, const DBT *, const DBT*) __attribute__((__visibility__("default")));
+
+namespace toku {
+
+ // a comparator object encapsulates the data necessary for
+ // comparing two keys in a fractal tree. it further understands
+ // that points may be positive or negative infinity.
+
+ class comparator {
+ void init(ft_compare_func cmp, DESCRIPTOR desc, uint8_t memcmp_magic) {
+ _cmp = cmp;
+ _fake_db->cmp_descriptor = desc;
+ _memcmp_magic = memcmp_magic;
+ }
+
+ public:
+ // This magic value is reserved to mean that the magic has not been set.
+ static const uint8_t MEMCMP_MAGIC_NONE = 0;
+
+ void create(ft_compare_func cmp, DESCRIPTOR desc, uint8_t memcmp_magic = MEMCMP_MAGIC_NONE) {
+ XCALLOC(_fake_db);
+ init(cmp, desc, memcmp_magic);
+ }
+
+ // inherit the attributes of another comparator, but keep our own
+ // copy of fake_db that is owned separately from the one given.
+ void inherit(const comparator &cmp) {
+ invariant_notnull(_fake_db);
+ invariant_notnull(cmp._cmp);
+ invariant_notnull(cmp._fake_db);
+ init(cmp._cmp, cmp._fake_db->cmp_descriptor, cmp._memcmp_magic);
+ }
+
+ // like inherit, but doesn't require that the this comparator
+ // was already created
+ void create_from(const comparator &cmp) {
+ XCALLOC(_fake_db);
+ inherit(cmp);
+ }
+
+ void destroy() {
+ toku_free(_fake_db);
+ }
+
+ const DESCRIPTOR_S *get_descriptor() const {
+ return _fake_db->cmp_descriptor;
+ }
+
+ ft_compare_func get_compare_func() const {
+ return _cmp;
+ }
+
+ uint8_t get_memcmp_magic() const {
+ return _memcmp_magic;
+ }
+
+ bool valid() const {
+ return _cmp != nullptr;
+ }
+
+ inline bool dbt_has_memcmp_magic(const DBT *dbt) const {
+ return *reinterpret_cast<const char *>(dbt->data) == _memcmp_magic;
+ }
+
+ int operator()(const DBT *a, const DBT *b) const {
+ if (__builtin_expect(toku_dbt_is_infinite(a) || toku_dbt_is_infinite(b), 0)) {
+ return toku_dbt_infinite_compare(a, b);
+ } else if (_memcmp_magic != MEMCMP_MAGIC_NONE
+ // If `a' has the memcmp magic..
+ && dbt_has_memcmp_magic(a)
+ // ..then we expect `b' to also have the memcmp magic
+ && __builtin_expect(dbt_has_memcmp_magic(b), 1)) {
+ return toku_builtin_compare_fun(nullptr, a, b);
+ } else {
+ // yikes, const sadness here
+ return _cmp(const_cast<DB *>(_fake_db), a, b);
+ }
+ }
+
+ private:
+ DB *_fake_db;
+ ft_compare_func _cmp;
+ uint8_t _memcmp_magic;
+ };
+
+} /* namespace toku */