85
85
under this License.
88
90
#ident "Copyright (c) 2007-2013 Tokutek Inc. All rights reserved."
89
91
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
95
94
#include <string.h>
98
#include <ft/fttypes.h>
96
#include "portability/memory.h"
100
typedef int (*ft_compare_func)(DB *db, const DBT *a, const DBT *b);
102
int toku_keycompare(const void *key1, uint32_t key1len, const void *key2, uint32_t key2len);
104
int toku_builtin_compare_fun (DB *, const DBT *, const DBT*) __attribute__((__visibility__("default")));
102
// a comparator object encapsulates the data necessary for
103
// comparing two keys in a fractal tree. it further understands
104
// that points may be positive or negative infinity.
108
void set_descriptor(DESCRIPTOR desc) {
109
m_fake_db.cmp_descriptor = desc;
112
void create(ft_compare_func cmp, DESCRIPTOR desc) {
114
memset(&m_fake_db, 0, sizeof(m_fake_db));
115
m_fake_db.cmp_descriptor = desc;
118
int compare(const DBT *a, const DBT *b) {
119
if (toku_dbt_is_infinite(a) || toku_dbt_is_infinite(b)) {
120
return toku_dbt_infinite_compare(a, b);
122
return m_cmp(&m_fake_db, a, b);
127
struct __toku_db m_fake_db;
128
ft_compare_func m_cmp;
108
// a comparator object encapsulates the data necessary for
109
// comparing two keys in a fractal tree. it further understands
110
// that points may be positive or negative infinity.
113
void init(ft_compare_func cmp, DESCRIPTOR desc, uint8_t memcmp_magic) {
115
_fake_db->cmp_descriptor = desc;
116
_memcmp_magic = memcmp_magic;
120
// This magic value is reserved to mean that the magic has not been set.
121
static const uint8_t MEMCMP_MAGIC_NONE = 0;
123
void create(ft_compare_func cmp, DESCRIPTOR desc, uint8_t memcmp_magic = MEMCMP_MAGIC_NONE) {
125
init(cmp, desc, memcmp_magic);
128
// inherit the attributes of another comparator, but keep our own
129
// copy of fake_db that is owned separately from the one given.
130
void inherit(const comparator &cmp) {
131
invariant_notnull(_fake_db);
132
invariant_notnull(cmp._cmp);
133
invariant_notnull(cmp._fake_db);
134
init(cmp._cmp, cmp._fake_db->cmp_descriptor, cmp._memcmp_magic);
137
// like inherit, but doesn't require that the this comparator
138
// was already created
139
void create_from(const comparator &cmp) {
148
const DESCRIPTOR_S *get_descriptor() const {
149
return _fake_db->cmp_descriptor;
152
ft_compare_func get_compare_func() const {
156
uint8_t get_memcmp_magic() const {
157
return _memcmp_magic;
161
return _cmp != nullptr;
164
inline bool dbt_has_memcmp_magic(const DBT *dbt) const {
165
return *reinterpret_cast<const char *>(dbt->data) == _memcmp_magic;
168
int operator()(const DBT *a, const DBT *b) const {
169
if (__builtin_expect(toku_dbt_is_infinite(a) || toku_dbt_is_infinite(b), 0)) {
170
return toku_dbt_infinite_compare(a, b);
171
} else if (_memcmp_magic != MEMCMP_MAGIC_NONE
172
// If `a' has the memcmp magic..
173
&& dbt_has_memcmp_magic(a)
174
// ..then we expect `b' to also have the memcmp magic
175
&& __builtin_expect(dbt_has_memcmp_magic(b), 1)) {
176
return toku_builtin_compare_fun(nullptr, a, b);
178
// yikes, const sadness here
179
return _cmp(const_cast<DB *>(_fake_db), a, b);
185
ft_compare_func _cmp;
186
uint8_t _memcmp_magic;
131
189
} /* namespace toku */