Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dict_view for (Base)Trie #35

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ src/*.html

*.so
build/

.idea/
.cache/
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.PHONY: build

build:
./update_c.sh
python setup.py build
python setup.py build_ext --inplace
1 change: 1 addition & 0 deletions libdatrie/datrie/libdatrie.def
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ trie_fread
trie_free
trie_save
trie_fwrite
trie_size
trie_is_dirty
trie_retrieve
trie_store
Expand Down
35 changes: 35 additions & 0 deletions libdatrie/datrie/trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct _Trie {
DArray *da;
Tail *tail;

uint32 size;
Bool is_dirty;
};

Expand Down Expand Up @@ -133,6 +134,7 @@ trie_new (const AlphaMap *alpha_map)
if (UNLIKELY (!trie->tail))
goto exit_da_created;

trie->size = 0;
trie->is_dirty = TRUE;
return trie;

Expand Down Expand Up @@ -203,6 +205,11 @@ trie_fread (FILE *file)
if (NULL == (trie->tail = tail_fread (file)))
goto exit_da_created;

uint32 counter = 0;
if (!trie_enumerate (trie, len_enumerator, &counter)) {
goto exit_trie_created;
}
trie->size = counter;
trie->is_dirty = FALSE;
return trie;

Expand Down Expand Up @@ -290,6 +297,19 @@ trie_fwrite (Trie *trie, FILE *file)
return 0;
}

/**
* @brief Check pending changes
*
* @param trie : the trie object
*
* @return total count of trie keys
*/
uint32
trie_size (const Trie *trie)
{
return trie->size;
}

/**
* @brief Check pending changes
*
Expand Down Expand Up @@ -431,6 +451,9 @@ trie_store_conditionally (Trie *trie,
res = trie_branch_in_branch (trie, s, key_str, data);
free (key_str);

if (res) {
trie->size++;
}
return res;
}
if (0 == *p)
Expand All @@ -455,6 +478,9 @@ trie_store_conditionally (Trie *trie,
res = trie_branch_in_tail (trie, s, tail_str, data);
free (tail_str);

if (res) {
trie->size++;
}
return res;
}
if (0 == *p)
Expand Down Expand Up @@ -580,6 +606,7 @@ trie_delete (Trie *trie, const AlphaChar *key)
da_set_base (trie->da, s, TRIE_INDEX_ERROR);
da_prune (trie->da, s);

trie->size--;
trie->is_dirty = TRUE;
return TRUE;
}
Expand Down Expand Up @@ -630,6 +657,14 @@ trie_enumerate (const Trie *trie, TrieEnumFunc enum_func, void *user_data)
}


Bool
len_enumerator (const AlphaChar *key, TrieData key_data, uint32 *counter_ptr)
{
(*counter_ptr)++;
return TRUE;
}


/*-------------------------------*
* STEPWISE QUERY OPERATIONS *
*-------------------------------*/
Expand Down
6 changes: 6 additions & 0 deletions libdatrie/datrie/trie.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ int trie_save (Trie *trie, const char *path);

int trie_fwrite (Trie *trie, FILE *file);

uint32 trie_size (const Trie *trie);

Bool trie_is_dirty (const Trie *trie);


Expand All @@ -150,6 +152,10 @@ Bool trie_enumerate (const Trie *trie,
TrieEnumFunc enum_func,
void *user_data);

Bool len_enumerator (const AlphaChar *key,
TrieData key_data,
uint32 *counter_ptr);


/*-------------------------------*
* STEPWISE QUERY OPERATIONS *
Expand Down
83 changes: 83 additions & 0 deletions libdatrie/tests/test_store-retrieve.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,34 @@ main ()
goto err_trie_not_created;
}

msg_step ("Check initial trie size");
if (trie_size(test_trie) != 0) {
printf ("Wrong trie size; expected 0, got %d.\n", trie_size(test_trie));
goto err_trie_size;
}

msg_step ("Delete non-existent key from trie and check size");
trie_delete (test_trie, (AlphaChar *)L"a");
if (trie_size(test_trie) != 0) {
printf ("Wrong trie size; expected 0, got %d.\n", trie_size(test_trie));
goto err_trie_size;
}
msg_step ("Add non-existent key with trie_store_if_absent and check size");
if (!trie_store_if_absent (test_trie, (AlphaChar *)L"a", TRIE_DATA_UNREAD)) {
printf ("Failed to add non-existing key '%ls'.\n", (AlphaChar *)L"a");
goto err_trie_created;
}
if (trie_size(test_trie) != 1) {
printf ("Wrong trie size; expected 1, got %d.\n", trie_size(test_trie));
goto err_trie_size;
}
msg_step ("Delete existing key from trie and check size");
trie_delete (test_trie, (AlphaChar *)L"a");
if (trie_size(test_trie) != 0) {
printf ("Wrong trie size; expected 0, got %d.\n", trie_size(test_trie));
goto err_trie_size;
}

/* store */
msg_step ("Adding data to trie");
for (dict_p = dict_src; dict_p->key; dict_p++) {
Expand All @@ -58,6 +86,51 @@ main ()
}
}

msg_step ("Check trie size");
if (trie_size(test_trie) != dict_src_n_entries()) {
printf ("Wrong trie size; expected %d, got %d.\n",
dict_src_n_entries(), trie_size(test_trie));
goto err_trie_size;
}

msg_step ("Update existing trie element and check trie size");
if (!trie_store (test_trie, dict_src[1].key, dict_src[1].data)) {
printf ("Failed to add key '%ls', data %d.\n",
dict_src[1].key, dict_src[1].data);
goto err_trie_created;
}
if (trie_size(test_trie) != dict_src_n_entries()) {
printf ("Wrong trie size; expected %d, got %d.\n",
dict_src_n_entries(), trie_size(test_trie));
goto err_trie_size;
}

msg_step ("Update existing trie element with trie_store_if_absent and check trie size");
if (trie_store_if_absent (test_trie, dict_src[1].key, dict_src[1].data)) {
printf ("Value for existing key '%ls' was updated with trie_store_if_absent.\n",
dict_src[1].key);
goto err_trie_created;
}
if (trie_size(test_trie) != dict_src_n_entries()) {
printf ("Wrong trie size; expected %d, got %d.\n",
dict_src_n_entries(), trie_size(test_trie));
goto err_trie_size;
}

msg_step ("Add trie element with wrong alphabet and check trie size");
if (trie_store (test_trie, (AlphaChar *)L"я", TRIE_DATA_UNREAD)) {
printf ("Key '%ls' with wrong alphabet was added.\n",
(AlphaChar *)L"я");
goto err_trie_created;
}
if (trie_size(test_trie) != dict_src_n_entries()) {
printf ("Wrong trie size; expected %d, got %d.\n",
dict_src_n_entries(), trie_size(test_trie));
goto err_trie_size;
}

// TODO: add key with wrong alphabet and check size?

/* retrieve */
msg_step ("Retrieving data from trie");
is_failed = FALSE;
Expand Down Expand Up @@ -99,6 +172,14 @@ main ()
goto err_trie_created;
}

msg_step ("Check trie size after deleting some entries.");
if (trie_size(test_trie) != (n_entries - (n_entries/3 + 1))) {
printf ("Wrong trie size; expected %d, got %d.\n",
(n_entries - (n_entries/3 + 1)), trie_size(test_trie));
goto err_trie_size;
}


/* retrieve */
msg_step ("Retrieving data from trie again after deletions");
for (dict_p = dict_src; dict_p->key; dict_p++) {
Expand Down Expand Up @@ -192,6 +273,8 @@ main ()
trie_state_free (trie_root_state);
err_trie_created:
trie_free (test_trie);
err_trie_size:
trie_free (test_trie);
err_trie_not_created:
return 1;
}
Expand Down
Loading