Skip to content

Commit b203552

Browse files
committed
C reproducer for range delete issue
1 parent 70c927e commit b203552

File tree

3 files changed

+113
-2
lines changed

3 files changed

+113
-2
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ BTREE_SYS = $(OBJDIR)/$(SRCDIR)/btree.o \
242242
# Note each test bin/unit/<x> also depends on obj/unit/<x>.o, as
243243
# defined above using unit_test_self_dependency.
244244
#
245+
$(BINDIR)/repro_bug_range_delete: $(OBJDIR)/repro_bug_range_delete.o $(LIBDIR)/libsplinterdb.so
246+
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
247+
245248
$(BINDIR)/$(UNITDIR)/misc_test: $(UTIL_SYS)
246249

247250
$(BINDIR)/$(UNITDIR)/util_test: $(UTIL_SYS)

include/splinterdb/limits.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
#ifndef __LIMITS_H__
1212
#define __LIMITS_H__
1313

14-
#define MAX_KEY_SIZE 24 /* bytes */
15-
#define MAX_MESSAGE_SIZE 128 /* bytes */
14+
#define MAX_KEY_SIZE 48 /* bytes */
15+
#define MAX_MESSAGE_SIZE 216 /* bytes */
1616
#define MAX_KEY_STR_LEN 128 /* bytes */
1717

1818
#endif // __LIMITS_H__

repro_bug_range_delete.c

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright 2021 VMware, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#include "splinterdb/splinterdb.h"
5+
#include "splinterdb/default_data_config.h"
6+
#include "tests/unit/unit_tests.h"
7+
#include "tests/functional/random.h"
8+
9+
#define KEY_SIZE (MAX_KEY_SIZE - 8)
10+
#define VALUE_SIZE 200
11+
12+
#define ASSERT_EQUAL(a, b) platform_assert((a) == (b))
13+
14+
static uint32
15+
naive_range_delete(const splinterdb *kvsb,
16+
char *start_key,
17+
size_t start_key_len,
18+
uint32 count)
19+
{
20+
fprintf(stderr, "\tcollecting keys to delete...\n");
21+
char *keys_to_delete = calloc(count, KEY_SIZE);
22+
23+
splinterdb_iterator *it;
24+
int rc = splinterdb_iterator_init(kvsb, &it, start_key_len, start_key);
25+
ASSERT_EQUAL(0, rc);
26+
27+
const char *key;
28+
const char *val;
29+
size_t key_len, val_len;
30+
uint32 num_found = 0;
31+
for (; splinterdb_iterator_valid(it); splinterdb_iterator_next(it)) {
32+
splinterdb_iterator_get_current(it, &key_len, &key, &val_len, &val);
33+
ASSERT_EQUAL(KEY_SIZE, key_len);
34+
memcpy(keys_to_delete + num_found * KEY_SIZE, key, KEY_SIZE);
35+
num_found++;
36+
if (num_found >= count) {
37+
break;
38+
}
39+
}
40+
rc = splinterdb_iterator_status(it);
41+
ASSERT_EQUAL(0, rc);
42+
splinterdb_iterator_deinit(it);
43+
44+
fprintf(stderr, "\tdeleting collected keys...\n");
45+
for (uint32 i = 0; i < num_found; i++) {
46+
char *key_to_delete = keys_to_delete + i * KEY_SIZE;
47+
splinterdb_delete(kvsb, KEY_SIZE, key_to_delete);
48+
}
49+
50+
free(keys_to_delete);
51+
return num_found;
52+
}
53+
54+
static void
55+
uniform_random_inserts(const splinterdb *kvsb,
56+
uint32 count,
57+
random_state *rand_state)
58+
{
59+
char key_buffer[KEY_SIZE] = {0};
60+
char value_buffer[VALUE_SIZE] = {0};
61+
62+
for (uint32 i = 0; i < count; i++) {
63+
random_bytes(rand_state, key_buffer, KEY_SIZE);
64+
random_bytes(rand_state, value_buffer, VALUE_SIZE);
65+
int rc = splinterdb_insert(
66+
kvsb, KEY_SIZE, key_buffer, VALUE_SIZE, value_buffer);
67+
ASSERT_EQUAL(0, rc);
68+
}
69+
}
70+
71+
72+
int
73+
main()
74+
{
75+
splinterdb_config cfg = (splinterdb_config){
76+
.filename = "db",
77+
.cache_size = 3 * Giga,
78+
.disk_size = 128 * Giga,
79+
};
80+
default_data_config_init(KEY_SIZE, VALUE_SIZE, &cfg.data_cfg);
81+
82+
splinterdb *kvsb;
83+
84+
int rc = splinterdb_create(&cfg, &kvsb);
85+
ASSERT_EQUAL(0, rc);
86+
87+
random_state rand_state;
88+
random_init(&rand_state, 42, 0);
89+
90+
const uint32 num_inserts = 5 * 1000 * 1000;
91+
fprintf(stderr, "loading data...\n");
92+
uniform_random_inserts(kvsb, num_inserts, &rand_state);
93+
fprintf(stderr, "loaded %u k/v pairs\n", num_inserts);
94+
95+
uint32 num_rounds = 5;
96+
for (uint32 round = 0; round < num_rounds; round++) {
97+
fprintf(stderr, "range delete round %d...\n", round);
98+
char start_key[4];
99+
random_bytes(&rand_state, start_key, sizeof(start_key));
100+
const uint32 num_to_delete = num_inserts / num_rounds;
101+
102+
uint32 num_deleted =
103+
naive_range_delete(kvsb, start_key, sizeof(start_key), num_to_delete);
104+
fprintf(stderr, "\tdeleted %u k/v pairs\n", num_deleted);
105+
}
106+
107+
splinterdb_close(kvsb);
108+
}

0 commit comments

Comments
 (0)