iondbproject / iondb

IonDB, a key-value datastore for resource constrained systems.
BSD 3-Clause "New" or "Revised" License
587 stars 48 forks source link

delete/get failed after delete first 3 records when key_type is key_type_null_terminated_string #91

Closed xianjimli closed 7 years ago

xianjimli commented 7 years ago

iondb is awesome library for embedded devices, but I meet a problem, can someone help me? Thanks in advance:)

delete/get failed after delete first 3 records when key_type is key_type_null_terminated_string, here is the test code:

#include <stdio.h>
#include <assert.h>
#include "../src/key_value/kv_system.h"
#include "../src/dictionary/dictionary.h"
#include "../src/dictionary/bpp_tree/bpp_tree_handler.h"
#include "../src/dictionary/ion_master_table.h"

int
main(
    void
) {
    int                         key_size, value_size;
    ion_key_type_t              key_type;
    ion_dictionary_handler_t    bpp_tree_handler;
    ion_dictionary_t            dictionary;
    ion_status_t                status;

    key_type    = key_type_null_terminated_string;
    key_size    = 12;
    value_size  = 20;

    ion_byte_t key[key_size];
    ion_byte_t  value[value_size];
    ion_byte_t  new_value[value_size];

    if (ion_init_master_table() != err_ok) {
        printf("Failed to create the master table\n");
        return 1;
    }

    bpptree_init(&bpp_tree_handler);
    if (ion_master_table_create_dictionary(&bpp_tree_handler, &dictionary, key_type, key_size, value_size, -1) != err_ok) {
        printf("Failed to create the dictionary\n");
        return 1;
    }

    int i;
    int n = 100;
    printf("stress test begin\n");
    for (i = 0; i < n; i++) {
        sprintf(key, "%d", i);
        sprintf((char *) value, "Hello World %d", i);
        printf("%d insert %s %s\n", i, key, value);
        status = dictionary_insert(&dictionary, key, value);
        assert(status.error == err_ok);
        status = dictionary_get(&dictionary, key, new_value);
        assert(status.error == err_ok && strcmp(value, new_value) == 0);
    }

    for (i = 0; i < n; i++) {
        sprintf(key, "%d", i);
        status = dictionary_delete(&dictionary, key);
        printf("%d delete %s return %d\n", i, key, status.error);
        assert(status.error == err_ok);
    }
    printf("stress test end\n");

    if ((ion_close_master_table() != err_ok) || (ion_delete_master_table() != err_ok)) {
        printf("Failed to close and delete the master table\n");
        return 1;
    }

    printf("Done\n");
    return 0;
}

if n < 36, it works well. Did I miss something?

xianjimli commented 7 years ago

it works for skip_list and open_address_hash, I think it is a bug of bbp_tree.

Stickerpants commented 7 years ago

Hi @xianjimli, thank you the bug report! This is a known issue with the B+ Tree implementation, documented here:

https://github.com/iondbproject/iondb/wiki/IonDB-Limitations-and-Known-Bugs#dictionary-api-issues

We are actively working to address the limitations and issues of the B+ Tree. For the time being, I would strongly recommend using the Flat File implementation in place of the B+ Tree. It is both strongly performant and minimal in memory usage.

xianjimli commented 7 years ago

OK, Thank you for your reply.

Stickerpants commented 7 years ago

Closing this for the time being, please feel free to add additional comments if you discover anything further. Thank you!