Implemented lfsr_rbyd_namelookup as a binary search, dropped search in fetch
Originally I thought doing a linear search during fetch was going to be the best route for name lookups, since we already needed a O(b) fetch, which set a hard ceiling for name lookup performance. But it turns out we don't need to fetch during btree name lookups unless we're also validating! Now that validation and lookups are disentangled, we can do a binary search over the rbyd to drop our name lookup down to O(log(b)^2). Two other motivations for this change: 1. This removes the name search from lfsr_rbyd_fetch, which has been surprisingly tricky to get right. 2. Now that lfsr_rbyd_fetch doesn't need to follow the create/delete history to find and reconstruct the state of names, we only need to know the create/delete state of tags post-fetch, freeing up the rbyd encoding to be more flexible. The next thing I plan to do is drop on-disk remove tags, for example. This drops the total btree namelookup cost from O(b log_b(n)) to O(log(b)^2 log_b(n)).
This commit is contained in:
+44
-44
@@ -2853,8 +2853,8 @@ code = '''
|
||||
lfs_size_t weight_;
|
||||
lfsr_data_t data_;
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aaa", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aaa", 3,
|
||||
&id_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
|
||||
'''
|
||||
|
||||
[cases.test_btree_find_one]
|
||||
@@ -2887,16 +2887,16 @@ code = '''
|
||||
lfs_size_t weight_;
|
||||
lfsr_data_t data_;
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aaa", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aaa", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 0);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "0", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aab", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aab", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 0);
|
||||
assert(weight_ == 1);
|
||||
@@ -2937,24 +2937,24 @@ code = '''
|
||||
lfs_size_t weight_;
|
||||
lfsr_data_t data_;
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aaa", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aaa", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 0);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "0", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aab", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aab", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 1);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "1", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aac", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aac", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 1);
|
||||
assert(weight_ == 1);
|
||||
@@ -2998,32 +2998,32 @@ code = '''
|
||||
lfs_size_t weight_;
|
||||
lfsr_data_t data_;
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aaa", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aaa", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 0);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "0", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aab", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aab", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 1);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "1", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aac", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aac", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 2);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "2", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aad", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aad", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 2);
|
||||
assert(weight_ == 1);
|
||||
@@ -3067,32 +3067,32 @@ code = '''
|
||||
lfs_size_t weight_;
|
||||
lfsr_data_t data_;
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aaa", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aaa", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 0);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "0", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aab", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aab", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 1);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "1", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aac", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aac", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 2);
|
||||
assert(weight_ == 1);
|
||||
lfsr_data_read(&lfs, data_, 0, buffer, 4) => 1;
|
||||
assert(memcmp(buffer, "2", 1) == 0);
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, "aad", 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, "aad", 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == 2);
|
||||
assert(weight_ == 1);
|
||||
@@ -3153,8 +3153,8 @@ code = '''
|
||||
alphas[(i/26/26) % 26], alphas[(i/26) % 26], alphas[i % 26]
|
||||
};
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, name, 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, name, 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == i);
|
||||
assert(weight_ == 1);
|
||||
@@ -3268,8 +3268,8 @@ code = '''
|
||||
lfs_size_t weight_;
|
||||
lfsr_data_t data_;
|
||||
for (lfs_size_t i = 0; i < sim_size; i++) {
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, sim_names[i], 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, sim_names[i], 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == i);
|
||||
assert(weight_ == 1);
|
||||
@@ -3339,8 +3339,8 @@ code = '''
|
||||
alphas[(i/26/26) % 26], alphas[(i/26) % 26], alphas[i % 26]
|
||||
};
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, name, 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, name, 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == i*W+W-1);
|
||||
assert(weight_ == W);
|
||||
@@ -3493,8 +3493,8 @@ code = '''
|
||||
weighted_id += sim_weights[j];
|
||||
}
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, sim_names[i], 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, sim_names[i], 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == weighted_id+sim_weights[i]-1);
|
||||
assert(weight_ == sim_weights[i]);
|
||||
@@ -3584,8 +3584,8 @@ code = '''
|
||||
// split btree
|
||||
lfs_size_t split_id;
|
||||
lfsr_data_t split_data;
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, name, 3,
|
||||
&split_id, NULL, NULL, NULL, NULL, &split_data) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, name, 3,
|
||||
&split_id, NULL, NULL, &split_data) => 0;
|
||||
uint8_t split_buf[4];
|
||||
lfsr_data_read(&lfs, split_data, 0, split_buf, 4) => 1;
|
||||
if (split_id > id) {
|
||||
@@ -3680,8 +3680,8 @@ code = '''
|
||||
lfs_size_t weight_;
|
||||
lfsr_data_t data_;
|
||||
for (lfs_size_t i = 0; i < sim_size; i++) {
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, sim_names[i], 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, sim_names[i], 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == i);
|
||||
assert(weight_ == 1);
|
||||
@@ -3787,8 +3787,8 @@ code = '''
|
||||
lfs_size_t split_id;
|
||||
lfs_size_t split_weight;
|
||||
lfsr_data_t split_data;
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, name, 3,
|
||||
&split_id, NULL, NULL, NULL, &split_weight,
|
||||
lfsr_btree_namelookup(&lfs, &btree, name, 3,
|
||||
&split_id, NULL, &split_weight,
|
||||
&split_data) => 0;
|
||||
uint8_t split_buf[4];
|
||||
lfsr_data_read(&lfs, split_data, 0, split_buf, 4) => 1;
|
||||
@@ -3912,8 +3912,8 @@ code = '''
|
||||
weighted_id += sim_weights[j];
|
||||
}
|
||||
|
||||
lfsr_btree_namelookupnext(&lfs, &btree, sim_names[i], 3,
|
||||
&id_, NULL, NULL, &tag_, &weight_, &data_) => 0;
|
||||
lfsr_btree_namelookup(&lfs, &btree, sim_names[i], 3,
|
||||
&id_, &tag_, &weight_, &data_) => 0;
|
||||
assert(tag_ == LFSR_TAG_INLINED);
|
||||
assert(id_ == weighted_id+sim_weights[i]-1);
|
||||
assert(weight_ == sim_weights[i]);
|
||||
|
||||
+183
-205
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user