Skip to content
Merged
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
3 changes: 2 additions & 1 deletion examples/splinterdb_custom_ipv4_addr_sortcmp_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,8 @@ do_iterate_from(splinterdb *spl_handle, const char *from_key)
// Initialize start key if initial search key was provided.
slice start_key =
(from_key ? slice_create(strlen(from_key), from_key) : NULL_SLICE);
int rc = splinterdb_iterator_init(spl_handle, &it, start_key);
int rc = splinterdb_iterator_init(
spl_handle, &it, start_key, greater_than_or_equal);

int i = 0;

Expand Down
3 changes: 2 additions & 1 deletion examples/splinterdb_intro_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ main()
" returning keys in lexicographic sort order:\n");

splinterdb_iterator *it = NULL;
rc = splinterdb_iterator_init(spl_handle, &it, NULL_SLICE);
rc = splinterdb_iterator_init(
spl_handle, &it, NULL_SLICE, greater_than_or_equal);

int i = 0;
for (; splinterdb_iterator_valid(it); splinterdb_iterator_next(it)) {
Expand Down
3 changes: 2 additions & 1 deletion examples/splinterdb_iterators_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ do_iterate_from(splinterdb *spl_handle, const char *from_key)
// Initialize start key if initial search key was provided.
slice start_key =
(from_key ? slice_create(strlen(from_key), from_key) : NULL_SLICE);
int rc = splinterdb_iterator_init(spl_handle, &it, start_key);
int rc = splinterdb_iterator_init(
spl_handle, &it, start_key, greater_than_or_equal);

int i = 0;

Expand Down
25 changes: 19 additions & 6 deletions include/splinterdb/splinterdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ Known issue: a live iterator may block inserts and deletes from the same thread.
Sample application code:

splinterdb_iterator* it;
int rc = splinterdb_iterator_init(kvs, &it, NULL_SLICE);
if (rc != 0) { ... handle error ... }
int rc = splinterdb_iterator_init(kvs, &it, NULL_SLICE,
greater_than_or_equal); if (rc != 0) { ... handle error ... }

slice key, value;

Expand All @@ -321,13 +321,26 @@ Sample application code:

typedef struct splinterdb_iterator splinterdb_iterator;

// should the iterator start at the first key that is <, <=, >, or >= than the
// start_key?
typedef enum comparison {
less_than,
less_than_or_equal,
greater_than,
greater_than_or_equal,
} comparison;


// Initialize a new iterator, starting at the given key
//
// If start_key is NULL_SLICE, the iterator will start before the minimum key
// If start_key is NULL_SLICE, the iterator will start at:
// - greater_than_or_equal: the minimum key
// - less_than_or_equal: the maximum key
int
splinterdb_iterator_init(splinterdb *kvs, // IN
splinterdb_iterator **iter, // OUT
slice start_key // IN
splinterdb_iterator_init(splinterdb *kvs, // IN
splinterdb_iterator **iter, // OUT
slice start_key, // IN
comparison start_type // IN
);

// Deinitialize an iterator
Expand Down
9 changes: 1 addition & 8 deletions src/iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,12 @@

#pragma once

#include "splinterdb/splinterdb.h"
#include "data_internal.h"
#include "vector.h"

typedef struct iterator iterator;

// for seek
typedef enum comparison {
less_than,
less_than_or_equal,
greater_than,
greater_than_or_equal,
} comparison;

typedef void (*iterator_curr_fn)(iterator *itor, key *curr_key, message *msg);
typedef bool32 (*iterator_bound_fn)(iterator *itor);
typedef platform_status (*iterator_step_fn)(iterator *itor);
Expand Down
16 changes: 11 additions & 5 deletions src/splinterdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "splinterdb/splinterdb.h"
#include "clockcache.h"
#include "data_internal.h"
#include "rc_allocator.h"
#include "core.h"
#include "lookup_result.h"
Expand Down Expand Up @@ -608,9 +609,10 @@ struct splinterdb_iterator {
};

int
splinterdb_iterator_init(splinterdb *kvs, // IN
splinterdb_iterator **iter, // OUT
slice user_start_key // IN
splinterdb_iterator_init(splinterdb *kvs, // IN
splinterdb_iterator **iter, // OUT
slice user_start_key, // IN
comparison start_type // IN
)
{
splinterdb_iterator *it = TYPED_MALLOC(kvs->spl.heap_id, it);
Expand All @@ -624,7 +626,11 @@ splinterdb_iterator_init(splinterdb *kvs, // IN
key start_key;

if (slice_is_null(user_start_key)) {
start_key = NEGATIVE_INFINITY_KEY;
if (start_type <= less_than_or_equal) {
start_key = POSITIVE_INFINITY_KEY;
} else {
start_key = NEGATIVE_INFINITY_KEY;
}
} else {
start_key = key_create_from_slice(TRUE, user_start_key);
}
Expand All @@ -634,7 +640,7 @@ splinterdb_iterator_init(splinterdb *kvs, // IN
NEGATIVE_INFINITY_KEY,
POSITIVE_INFINITY_KEY,
start_key,
greater_than_or_equal,
start_type,
UINT64_MAX);
if (!SUCCESS(rc)) {
platform_free(kvs->spl.heap_id, *iter);
Expand Down
38 changes: 25 additions & 13 deletions tests/unit/splinterdb_quick_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,8 @@ CTEST2(splinterdb_quick, test_basic_iterator)

splinterdb_iterator *it = NULL;

rc = splinterdb_iterator_init(data->kvsb, &it, NULL_SLICE);
rc = splinterdb_iterator_init(
data->kvsb, &it, NULL_SLICE, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

for (; splinterdb_iterator_valid(it); splinterdb_iterator_next(it)) {
Expand All @@ -475,7 +476,8 @@ CTEST2(splinterdb_quick, test_basic_iterator)
CTEST2(splinterdb_quick, test_empty_iterator)
{
splinterdb_iterator *it = NULL;
int rc = splinterdb_iterator_init(data->kvsb, &it, NULL_SLICE);
int rc = splinterdb_iterator_init(
data->kvsb, &it, NULL_SLICE, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

ASSERT_FALSE(splinterdb_iterator_valid(it));
Expand Down Expand Up @@ -506,7 +508,8 @@ CTEST2(splinterdb_quick, test_splinterdb_iterator_with_startkey)
// Initialize the i'th key
snprintf(key, sizeof(key), key_fmt, ictr);
slice start_key = slice_create(strlen(key), key);
rc = splinterdb_iterator_init(data->kvsb, &it, start_key);
rc = splinterdb_iterator_init(
data->kvsb, &it, start_key, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

bool32 is_valid = splinterdb_iterator_valid(it);
Expand Down Expand Up @@ -540,7 +543,8 @@ CTEST2(splinterdb_quick, test_splinterdb_iterator_with_non_existent_startkey)
char *keystring = "unknownKey";

slice start_key = slice_create(strlen(keystring), keystring);
rc = splinterdb_iterator_init(data->kvsb, &it, start_key);
rc = splinterdb_iterator_init(
data->kvsb, &it, start_key, greater_than_or_equal);

// Iterator should be invalid, as lookup key is non-existent.
bool32 is_valid = splinterdb_iterator_valid(it);
Expand All @@ -553,7 +557,8 @@ CTEST2(splinterdb_quick, test_splinterdb_iterator_with_non_existent_startkey)
// before 'key...', which is what key's format is.)
keystring = "UnknownKey";
start_key = slice_create(strlen(keystring), keystring);
rc = splinterdb_iterator_init(data->kvsb, &it, start_key);
rc = splinterdb_iterator_init(
data->kvsb, &it, start_key, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

int ictr = 0;
Expand Down Expand Up @@ -606,7 +611,8 @@ CTEST2(splinterdb_quick,

splinterdb_iterator *it = NULL;
slice start_key = slice_create(strlen(key), key);
rc = splinterdb_iterator_init(data->kvsb, &it, start_key);
rc = splinterdb_iterator_init(
data->kvsb, &it, start_key, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

bool32 is_valid = splinterdb_iterator_valid(it);
Expand All @@ -625,7 +631,8 @@ CTEST2(splinterdb_quick,

snprintf(key, sizeof(key), key_fmt, kctr);
start_key = slice_create(strlen(key), key);
rc = splinterdb_iterator_init(data->kvsb, &it, start_key);
rc = splinterdb_iterator_init(
data->kvsb, &it, start_key, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

is_valid = splinterdb_iterator_valid(it);
Expand All @@ -643,7 +650,8 @@ CTEST2(splinterdb_quick,
kctr = 5;
snprintf(key, sizeof(key), key_fmt, kctr);
start_key = slice_create(strlen(key), key);
rc = splinterdb_iterator_init(data->kvsb, &it, start_key);
rc = splinterdb_iterator_init(
data->kvsb, &it, start_key, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

is_valid = splinterdb_iterator_valid(it);
Expand All @@ -661,7 +669,8 @@ CTEST2(splinterdb_quick,
kctr = minkey + 3 * num_inserts;
snprintf(key, sizeof(key), key_fmt, kctr);
start_key = slice_create(strlen(key), key);
rc = splinterdb_iterator_init(data->kvsb, &it, start_key);
rc = splinterdb_iterator_init(
data->kvsb, &it, start_key, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

is_valid = splinterdb_iterator_valid(it);
Expand Down Expand Up @@ -944,7 +953,8 @@ CTEST2(splinterdb_quick, test_iterator_custom_comparator)
ASSERT_EQUAL(0, rc);

splinterdb_iterator *it = NULL;
rc = splinterdb_iterator_init(data->kvsb, &it, NULL_SLICE);
rc = splinterdb_iterator_init(
data->kvsb, &it, NULL_SLICE, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

int i = 0;
Expand Down Expand Up @@ -986,7 +996,8 @@ CTEST2(splinterdb_quick, test_iterator_init_bug)

// Iterator init should find nothing when no keys were inserted, yet.
splinterdb_iterator *it = NULL;
rc = splinterdb_iterator_init(data->kvsb, &it, NULL_SLICE);
rc = splinterdb_iterator_init(
data->kvsb, &it, NULL_SLICE, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

bool32 iter_valid = splinterdb_iterator_valid(it);
Expand All @@ -1000,7 +1011,8 @@ CTEST2(splinterdb_quick, test_iterator_init_bug)
ASSERT_EQUAL(0, rc);

it = NULL;
rc = splinterdb_iterator_init(data->kvsb, &it, NULL_SLICE);
rc = splinterdb_iterator_init(
data->kvsb, &it, NULL_SLICE, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

iter_valid = splinterdb_iterator_valid(it);
Expand Down Expand Up @@ -1200,7 +1212,7 @@ test_two_step_iterator(splinterdb *kvsb,
{
int rc;
splinterdb_iterator *it = NULL;
rc = splinterdb_iterator_init(kvsb, &it, start_key);
rc = splinterdb_iterator_init(kvsb, &it, start_key, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

for (int i = start_i; i < num_keys; i++) {
Expand Down
7 changes: 5 additions & 2 deletions tests/unit/splinterdb_stress_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ CTEST2(splinterdb_stress, test_iterator_over_many_kvs)
splinterdb_iterator *it = NULL;
snprintf(key_str, sizeof(key_str), "key-%08x", inserts);
slice start_key = slice_create(sizeof(key_str), key_str);
ASSERT_EQUAL(0, splinterdb_iterator_init(data->kvsb, &it, start_key));
ASSERT_EQUAL(0,
splinterdb_iterator_init(
data->kvsb, &it, start_key, greater_than_or_equal));

// assert that the iterator is in the state we expect
ASSERT_FALSE(splinterdb_iterator_valid(it));
Expand Down Expand Up @@ -316,7 +318,8 @@ naive_range_delete(splinterdb *kvsb, slice start_key, uint32 count)

splinterdb_iterator *it;

int rc = splinterdb_iterator_init(kvsb, &it, start_key);
int rc =
splinterdb_iterator_init(kvsb, &it, start_key, greater_than_or_equal);
ASSERT_EQUAL(0, rc);

slice key, value;
Expand Down
Loading