Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions examples/splinterdb_custom_ipv4_addr_sortcmp_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ configure_splinter_instance(splinterdb_config *splinterdb_cfg,
uint64 cache_size);

int
custom_key_compare(const data_config *cfg, slice key1, slice key2);
custom_key_compare(const data_config *cfg, user_key key1, user_key key2);

int
ip4_ipaddr_keycmp(const char *key1,
Expand Down Expand Up @@ -208,12 +208,12 @@ configure_splinter_instance(splinterdb_config *splinterdb_cfg,
* -----------------------------------------------------------------------------
*/
int
custom_key_compare(const data_config *cfg, slice key1, slice key2)
custom_key_compare(const data_config *cfg, user_key key1, user_key key2)
{
return ip4_ipaddr_keycmp((const char *)slice_data(key1),
slice_length(key1),
(const char *)slice_data(key2),
slice_length(key2));
return ip4_ipaddr_keycmp((const char *)slice_data(key1.key),
slice_length(key1.key),
(const char *)slice_data(key2.key),
slice_length(key2.key));
}

/*
Expand Down
15 changes: 12 additions & 3 deletions include/splinterdb/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,18 @@ merge_accumulator_set_class(merge_accumulator *ma, message_type type);

typedef struct data_config data_config;

typedef int (*key_compare_fn)(const data_config *cfg, slice key1, slice key2);
typedef struct user_key {
slice key;
bool32 is_query_key;
} user_key;

typedef uint32 (*key_hash_fn)(const void *input, size_t length, uint32 seed);
typedef int (*key_compare_fn)(const data_config *cfg,
user_key key1,
user_key key2);

typedef uint32 (*key_hash_fn)(const data_config *cfg,
user_key key,
uint32 seed);

// Given two messages, old_message and new_message, merge them
// and return the result in new_message.
Expand All @@ -133,7 +142,7 @@ typedef int (*merge_tuple_final_fn)(const data_config *cfg,
merge_accumulator *oldest_message);

typedef void (*key_to_str_fn)(const data_config *cfg,
slice key,
user_key key,
char *str,
uint64 max_len);

Expand Down
6 changes: 5 additions & 1 deletion include/splinterdb/splinterdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ splinterdb_update(splinterdb *kvsb, slice key, slice delta);
// Lookups

// Size of opaque data required to hold a lookup result
#define SPLINTERDB_LOOKUP_BUFSIZE (10 * sizeof(void *))
#define SPLINTERDB_LOOKUP_BUFSIZE (18 * sizeof(void *))

// A lookup result is stored and parsed from here
//
Expand Down Expand Up @@ -239,6 +239,10 @@ splinterdb_lookup_result_value(const splinterdb_lookup_result *result, // IN
slice *value // OUT
);

int
splinterdb_lookup_result_key(const splinterdb_lookup_result *result, // IN
slice *key // OUT
);

// Lookup the message for a given key
//
Expand Down
76 changes: 58 additions & 18 deletions src/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,11 +475,11 @@ btree_find_pivot(const btree_config *cfg,

while (lo < hi) {
int64 mid = (lo + hi) / 2;
int cmp = btree_key_compare(cfg, btree_get_pivot(cfg, hdr, mid), target);
int cmp = btree_key_compare(cfg, target, btree_get_pivot(cfg, hdr, mid));
if (cmp == 0) {
*found = TRUE;
return mid;
} else if (cmp < 0) {
} else if (cmp > 0) {
lo = mid + 1;
} else {
hi = mid;
Expand Down Expand Up @@ -518,11 +518,11 @@ btree_find_tuple(const btree_config *cfg,
while (lo < hi) {
int64 mid = (lo + hi) / 2;
int cmp =
btree_key_compare(cfg, btree_get_tuple_key(cfg, hdr, mid), target);
btree_key_compare(cfg, target, btree_get_tuple_key(cfg, hdr, mid));
if (cmp == 0) {
*found = TRUE;
return mid;
} else if (cmp < 0) {
} else if (cmp > 0) {
lo = mid + 1;
} else {
hi = mid;
Expand Down Expand Up @@ -2186,33 +2186,39 @@ btree_lookup_with_ref_async(btree_lookup_async_state *state, uint64 depth)
int64 idx = btree_find_tuple(
state->cfg, state->node.hdr, state->target, &state->found);
if (state->found) {
state->msg = leaf_entry_message(
btree_get_leaf_entry(state->cfg, state->node.hdr, idx));
leaf_entry *entry =
btree_get_leaf_entry(state->cfg, state->node.hdr, idx);
state->found_key = leaf_entry_key(entry);
state->msg = leaf_entry_message(entry);
} else {
btree_node_unget(state->cc, state->cfg, &state->node);
}
async_return(state);
}


static inline void
static inline platform_status
btree_lookup_with_ref(cache *cc, // IN
const btree_config *cfg, // IN
uint64 root_addr, // IN
page_type type, // IN
key target, // IN
btree_node *node, // OUT
key *found_key, // OUT
message *msg, // OUT
bool32 *found) // OUT
{
platform_status rc = STATUS_OK;
btree_lookup_node(cc, cfg, root_addr, target, 0, type, node, NULL);
int64 idx = btree_find_tuple(cfg, node->hdr, target, found);
if (*found) {
leaf_entry *entry = btree_get_leaf_entry(cfg, node->hdr, idx);
*found_key = leaf_entry_key(entry);
*msg = leaf_entry_message(entry);
} else {
btree_node_unget(cc, cfg, node);
}
return rc;
}

async_status
Expand All @@ -2221,12 +2227,20 @@ btree_lookup_async(btree_lookup_async_state *state)
async_begin(state, 0);

async_await_subroutine(state, btree_lookup_with_ref_async);
bool32 success = TRUE;

platform_status rc = STATUS_OK;
if (state->found) {
success = merge_accumulator_copy_message(state->result, state->msg);
if (state->keybuf != NULL) {
rc = key_buffer_copy_key(state->keybuf, state->found_key);
}
bool32 success =
merge_accumulator_copy_message(state->result, state->msg);
if (!success) {
rc = STATUS_NO_MEMORY;
}
btree_node_unget(state->cc, state->cfg, &state->node);
}
async_return(state, success ? STATUS_OK : STATUS_NO_MEMORY);
async_return(state, rc);
}


Expand All @@ -2236,18 +2250,25 @@ btree_lookup(cache *cc, // IN
uint64 root_addr, // IN
page_type type, // IN
key target, // IN
key_buffer *keybuf, // OUT
merge_accumulator *result) // OUT
{
btree_node node;
key found_key;
message data;
platform_status rc = STATUS_OK;
bool32 local_found;

btree_lookup_with_ref(
cc, cfg, root_addr, type, target, &node, &data, &local_found);
cc, cfg, root_addr, type, target, &node, &found_key, &data, &local_found);
if (local_found) {
if (keybuf != NULL) {
rc = key_buffer_copy_key(keybuf, found_key);
}
bool32 success = merge_accumulator_copy_message(result, data);
rc = success ? STATUS_OK : STATUS_NO_MEMORY;
if (!success) {
rc = STATUS_NO_MEMORY;
}
btree_node_unget(cc, cfg, &node);
}
return rc;
Expand All @@ -2259,21 +2280,35 @@ btree_lookup_and_merge(cache *cc, // IN
uint64 root_addr, // IN
page_type type, // IN
key target, // IN
key_buffer *keybuf, // OUT
merge_accumulator *data, // OUT
bool32 *local_found) // OUT
{
btree_node node;
key found_key;
message local_data;
platform_status rc = STATUS_OK;

log_trace_key(target, "btree_lookup");

btree_lookup_with_ref(
cc, cfg, root_addr, type, target, &node, &local_data, local_found);
btree_lookup_with_ref(cc,
cfg,
root_addr,
type,
target,
&node,
&found_key,
&local_data,
local_found);
if (*local_found) {
if (keybuf != NULL) {
rc = key_buffer_copy_key(keybuf, found_key);
}
if (merge_accumulator_is_null(data)) {
bool32 success = merge_accumulator_copy_message(data, local_data);
rc = success ? STATUS_OK : STATUS_NO_MEMORY;
if (!success) {
rc = STATUS_NO_MEMORY;
}
} else if (btree_merge_tuples(cfg, target, local_data, data)) {
rc = STATUS_NO_MEMORY;
}
Expand Down Expand Up @@ -2313,10 +2348,15 @@ btree_lookup_and_merge_async(btree_lookup_async_state *state)

platform_status rc = STATUS_OK;
if (state->found) {
if (state->keybuf != NULL) {
rc = key_buffer_copy_key(state->keybuf, state->found_key);
}
if (merge_accumulator_is_null(state->result)) {
bool32 success =
merge_accumulator_copy_message(state->result, state->msg);
rc = success ? STATUS_OK : STATUS_NO_MEMORY;
if (!success) {
rc = STATUS_NO_MEMORY;
}
} else if (btree_merge_tuples(
state->cfg, state->target, state->msg, state->result))
{
Expand Down Expand Up @@ -3057,10 +3097,10 @@ btree_pack_loop(btree_pack_req *req, // IN/OUT

log_trace_key(tuple_key, "btree_pack_loop (bottom)");

if (req->hash) {
if (req->cfg->data_cfg->key_hash != NULL) {
platform_assert(req->num_tuples < req->max_tuples);
req->fingerprint_arr[req->num_tuples] =
req->hash(key_data(tuple_key), key_length(tuple_key), req->seed);
data_key_hash(req->cfg->data_cfg, tuple_key, req->seed);
}

req->num_tuples++;
Expand Down
22 changes: 16 additions & 6 deletions src/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ typedef struct btree_pack_req {
const btree_config *cfg;
iterator *itor; // the itor which is being packed
uint64 max_tuples;
hash_fn hash; // hash function used for calculating filter_hash
unsigned int seed; // seed used for calculating filter_hash
uint32 *fingerprint_arr; // IN/OUT: hashes of the keys in the tree

Expand Down Expand Up @@ -208,6 +207,7 @@ btree_lookup(cache *cc,
uint64 root_addr,
page_type type,
key target,
key_buffer *keybuf,
merge_accumulator *result);

static inline bool32
Expand All @@ -222,6 +222,7 @@ btree_lookup_and_merge(cache *cc,
uint64 root_addr,
page_type type,
key target,
key_buffer *keybuf,
merge_accumulator *data,
bool32 *local_found);

Expand All @@ -232,6 +233,7 @@ DEFINE_ASYNC_STATE(btree_lookup_async_state, 3,
param, uint64, root_addr,
param, page_type, type,
param, key, target,
param, key_buffer *, keybuf,
param, merge_accumulator *, result,
param, async_callback_fn, callback,
param, void *, callback_arg,
Expand All @@ -242,6 +244,7 @@ DEFINE_ASYNC_STATE(btree_lookup_async_state, 3,
local, btree_node, child_node,
local, uint32, h,
local, bool32, found,
local, key, found_key,
local, message, msg,
local, page_get_async_state_buffer, cache_get_state)
// clang-format on
Expand All @@ -253,12 +256,21 @@ btree_lookup_and_merge_async_state_init(btree_lookup_async_state *state,
uint64 root_addr,
page_type type,
key target,
key_buffer *keybuf,
merge_accumulator *result,
async_callback_fn callback,
void *callback_arg)
{
btree_lookup_async_state_init(
state, cc, cfg, root_addr, type, target, result, callback, callback_arg);
btree_lookup_async_state_init(state,
cc,
cfg,
root_addr,
type,
target,
keybuf,
result,
callback,
callback_arg);
}

async_status
Expand Down Expand Up @@ -289,7 +301,6 @@ btree_pack_req_init(btree_pack_req *req,
const btree_config *cfg,
iterator *itor,
uint64 max_tuples,
hash_fn hash,
unsigned int seed,
platform_heap_id hid)
{
Expand All @@ -298,9 +309,8 @@ btree_pack_req_init(btree_pack_req *req,
req->cfg = cfg;
req->itor = itor;
req->max_tuples = max_tuples;
req->hash = hash;
req->seed = seed;
if (hash != NULL && max_tuples > 0) {
if (cfg->data_cfg->key_hash != NULL && max_tuples > 0) {
req->fingerprint_arr =
TYPED_ARRAY_ZALLOC(hid, req->fingerprint_arr, max_tuples);

Expand Down
Loading
Loading