fixed not needing double loops but fixing bug of not first finding results
This commit is contained in:
parent
cdd9c77892
commit
a26b411fd4
16
main.cpp
16
main.cpp
@ -105,6 +105,22 @@ void test_basics(amap mapdo, void *map) {
|
||||
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaningless1", NULL)));
|
||||
assert(*iptr == 42);
|
||||
assert(iptr == &i);
|
||||
|
||||
/* Check the case where we have same 8-long prefix for multiple and they should be different */
|
||||
int long_1 = 1;
|
||||
int long_2 = 2;
|
||||
int long_3 = 3;
|
||||
|
||||
assert(NULL != mapdo(map, AMAP_SET, "very_long_test_key_1", &long_1));
|
||||
assert(NULL != mapdo(map, AMAP_SET, "very_long_test_key_2", &long_2));
|
||||
assert(NULL != mapdo(map, AMAP_SET, "very_long_test_key_3", &long_3));
|
||||
|
||||
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "very_long_test_key_1", NULL)));
|
||||
assert(*iptr == 1);
|
||||
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "very_long_test_key_2", NULL)));
|
||||
assert(*iptr == 2);
|
||||
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "very_long_test_key_3", NULL)));
|
||||
assert(*iptr == 3);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
64
simap.h
64
simap.h
@ -128,46 +128,44 @@ static inline simap_ptr64 *simap_search_internal(simap_instance *map, const char
|
||||
/* Lookup prefix (fast-key) - hopefully this gets vectorized (should be)!!! */
|
||||
auint64 *base = (auint64 *) (map->base);
|
||||
auint64 *end = (auint64 *)((uint8_t *)base + (map->usage_end));
|
||||
auint64 *tipp = NULL;
|
||||
auint64 *nutipp = make_tipp(base, prefix.u64, end);
|
||||
while(tipp != nutipp) {
|
||||
tipp = nutipp;
|
||||
while(tipp < end) {
|
||||
/* Fast lookup, because found prefix */
|
||||
assert((*tipp == prefix.u64));
|
||||
auint64 *tipp = make_tipp(base, prefix.u64, end);
|
||||
while(tipp < end) {
|
||||
|
||||
/* First check the remains of the string (only if needed) */
|
||||
if(!is_smallkey) {
|
||||
char *tippremains = (char *)((uint8_t *)tipp + sizeof(uint64_t));
|
||||
if(strcmp(keyremains, tippremains) != 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* Need detailed lookup, because found the prefix */
|
||||
assert((*tipp == prefix.u64));
|
||||
|
||||
simap_ptr64 *ptr = (simap_ptr64 *)((uint8_t *) (tipp - 2));
|
||||
|
||||
/* Check back & forth (jump validation) */
|
||||
uint32_t previ = *((uint32_t *)(tipp - 1));
|
||||
if(previ == (uint32_t) -1) {
|
||||
/* Expect it be good if it was first insert ever? Statistically rare to be not like it */
|
||||
return ptr;
|
||||
}
|
||||
uint32_t prevnexi = *(uint32_t *)(((uint8_t *)base) + previ
|
||||
+ sizeof(simap_ptr64)
|
||||
+ sizeof(uint32_t));
|
||||
|
||||
auint64 *retipp = (auint64 *)(((uint8_t *)base + prevnexi)
|
||||
+ sizeof(simap_ptr64) + sizeof(uint32_t) +
|
||||
+ sizeof(uint32_t));
|
||||
|
||||
if(retipp != tipp) {
|
||||
/* First check the remains of the string (only if needed) */
|
||||
if(!is_smallkey) {
|
||||
char *tippremains = (char *)((uint8_t *)tipp + sizeof(uint64_t));
|
||||
if(strcmp(keyremains, tippremains) != 0) {
|
||||
tipp = make_tipp(tipp + 1, prefix.u64, end);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Can have the (statistically checked) pointer */
|
||||
simap_ptr64 *ptr = (simap_ptr64 *)((uint8_t *) (tipp - 2));
|
||||
|
||||
/* Check back & forth (jump validation) */
|
||||
uint32_t previ = *((uint32_t *)(tipp - 1));
|
||||
if(previ == (uint32_t) -1) {
|
||||
/* Expect it be good if it was first insert ever? Statistically rare to be not like it */
|
||||
return ptr;
|
||||
}
|
||||
nutipp = make_tipp((auint64 *) base, prefix.u64, end);
|
||||
uint32_t prevnexi = *(uint32_t *)(((uint8_t *)base) + previ
|
||||
+ sizeof(simap_ptr64)
|
||||
+ sizeof(uint32_t));
|
||||
|
||||
auint64 *retipp = (auint64 *)(((uint8_t *)base + prevnexi)
|
||||
+ sizeof(simap_ptr64) + sizeof(uint32_t) +
|
||||
+ sizeof(uint32_t));
|
||||
|
||||
if(retipp != tipp) {
|
||||
tipp = make_tipp(tipp + 1, prefix.u64, end);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Can have the (statistically checked) pointer */
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Haven't found anything */
|
||||
|
Loading…
x
Reference in New Issue
Block a user