int main (void) { Trie *test_trie; DictRec *dict_p; const AlphaChar **nonalpha_key; TrieData trie_data; Bool is_fail; msg_step ("Preparing trie"); test_trie = en_trie_new (); if (!test_trie) { fprintf (stderr, "Fail to create test trie\n"); goto err_trie_not_created; } /* store */ msg_step ("Adding data to trie"); for (dict_p = dict_src; dict_p->key; dict_p++) { if (!trie_store (test_trie, dict_p->key, dict_p->data)) { printf ("Failed to add key '%ls', data %d.\n", (wchar_t *)dict_p->key, dict_p->data); goto err_trie_created; } } /* test storing keys with non-alphabet chars */ is_fail = FALSE; for (nonalpha_key = nonalpha_src; *nonalpha_key; nonalpha_key++) { if (trie_retrieve (test_trie, *nonalpha_key, &trie_data)) { printf ("False duplication on key '%ls', with existing data %d.\n", (wchar_t *)*nonalpha_key, trie_data); is_fail = TRUE; } if (trie_store (test_trie, *nonalpha_key, TRIE_DATA_UNREAD)) { printf ("Wrongly added key '%ls' containing non-alphanet char\n", (wchar_t *)*nonalpha_key); is_fail = TRUE; } } if (is_fail) goto err_trie_created; trie_free (test_trie); return 0; err_trie_created: trie_free (test_trie); err_trie_not_created: return 1; }
static int subscribe_channel(sub_client *c, sds channel) { TrieData data; size_t len; AlphaChar *chan_alpha; len = sdslen(channel); chan_alpha = (AlphaChar *) malloc(sizeof(AlphaChar) * len + 1); conv_to_alpha(server.dflt_to_alpha_conv, channel, chan_alpha, len+1); /* channel not exists in trie, create */ if (!trie_retrieve(server.sub_trie, chan_alpha, &data)) { if (!trie_store(server.sub_trie, chan_alpha, TRIE_DATA_DFLT)) { srv_log(LOG_ERROR, "Failed to insert key %s into sub trie", channel); return SUBCLI_ERR; } /* create hashtable mapping from subscribe-channel to client id set */ hset *hs = hset_create(SUB_SET_LEN); hset_insert(hs, CLIENT_ID_LEN, c->id, c); if (ght_insert(server.subscibe_table, hs, len, channel) == -1) { hset_release(hs); srv_log(LOG_ERROR, "Failed to insert key[%s]->set into subscribe hashtable", channel); return SUBCLI_ERR; } } return SUBCLI_OK; }
int main (void) { AlphaMap *alpha_map; Trie *test_trie; AlphaChar key[3]; TrieData data; msg_step ("Preparing alpha map"); alpha_map = alpha_map_new (); if (!alpha_map) { printf ("Fail to allocate alpha map\n"); goto err_alpha_map_not_created; } if (alpha_map_add_range (alpha_map, 0x00, 0xff) != 0) { printf ("Fail to add full alpha map range\n"); goto err_alpha_map_created; } msg_step ("Preparing trie"); test_trie = trie_new (alpha_map); alpha_map_free (alpha_map); if (!test_trie) { printf ("Fail to create test trie\n"); goto err_alpha_map_created; } msg_step ("Storing key to test trie"); key[0] = 0xff; key[1] = 0xff; key[2] = 0; if (!trie_store (test_trie, key, TEST_DATA)) { printf ("Fail to store key to test trie\n"); goto err_trie_created; } msg_step ("Retrieving data from test trie"); if (!trie_retrieve (test_trie, key, &data)) { printf ("Fail to retrieve key from test trie\n"); goto err_trie_created; } if (TEST_DATA != data) { printf ("Retrieved data = %d, not %d\n", data, TEST_DATA); goto err_trie_created; } msg_step ("Freeing test trie"); trie_free (test_trie); return 0; err_trie_created: trie_free (test_trie); err_alpha_map_created: alpha_map_free (alpha_map); err_alpha_map_not_created: return 1; }
Bool sb_trie_store (SBTrie *sb_trie, const SBChar *key, TrieData data) { TrieChar *trie_key; Bool ret; trie_key = sb_map_char_to_alphabet_str (sb_trie->alpha_map, key); ret = trie_store (sb_trie->trie, trie_key, data); free (trie_key); return ret; }
/* * call-seq: * add(key) * add(key,value) * * Add a key, or a key and value to the Trie. If you add a key without a value it assumes true for the value. * */ static VALUE rb_trie_add(VALUE self, VALUE args) { Trie *trie; Data_Get_Struct(self, Trie, trie); int size = RARRAY_LEN(args); if(size < 1 || size > 2) return Qnil; VALUE key; key = RARRAY_PTR(args)[0]; StringValue(key); TrieData value = size == 2 ? RARRAY_PTR(args)[1] : TRIE_DATA_ERROR; if(trie_store(trie, (TrieChar*)RSTRING_PTR(key), value)) return Qtrue; else return Qnil; }
bool ATTrie :: store(const QString & key, int index) { /*if (node == NULL) return false;*/ if (data->trie == NULL) return false; if (key.length() > AT_ALPHA_KEY_MAX_LENGTH - 1) return false; for (int i = 0; i < key.length(); i++) data->alpha_key[i] = key[i].unicode(); data->alpha_key[key.length()] = 0; TrieData d = (TrieData) index; Bool ret = trie_store(data->trie, data->alpha_key, d); return ret == TRUE; }
/* * call-seq: * add(key) * add(key,value) * * Add a key, or a key and value to the Trie. If you add a key without a value it assumes true for the value. * */ static VALUE rb_trie_add(VALUE self, VALUE args) { Trie *trie; Data_Get_Struct(self, Trie, trie); int size = RARRAY_LEN(args); if(size < 1 || size > 2) return Qnil; VALUE key; key = RARRAY_PTR(args)[0]; StringValue(key); if (size == 2 && TYPE( RARRAY_PTR(args)[1]) != T_FIXNUM){ VALUE rb_eIOError = rb_const_get(rb_cObject, rb_intern("ArgumentError")); rb_raise(rb_eIOError, "value should is a numeric"); } TrieData value = size == 2 ? NUM2INT(RARRAY_PTR(args)[1]) : TRIE_DATA_ERROR; if(trie_store(trie, (TrieChar*)RSTRING_PTR(key), value)) return Qtrue; else return Qnil; }
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { { "update", no_argument, NULL, 'u' }, { "root", required_argument, NULL, 'r' }, { "test", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, {} }; const char *test = NULL; const char *root = ""; char *udev_hwdb_path = UDEV_HWDB_BIN; bool update = false; struct trie *trie = NULL; int err; int rc = EXIT_SUCCESS; for (;;) { int option; option = getopt_long(argc, argv, "ut:r:h", options, NULL); if (option == -1) break; switch (option) { case 'u': update = true; break; case 't': test = optarg; break; case 'r': root = optarg; break; case 'h': help(); return EXIT_SUCCESS; } } if (!update && !test) { help(); return EXIT_SUCCESS; } if (update) { char **files, **f; trie = calloc(sizeof(struct trie), 1); if (!trie) { rc = EXIT_FAILURE; goto out; } /* string store */ trie->strings = strbuf_new(); if (!trie->strings) { rc = EXIT_FAILURE; goto out; } /* index */ trie->root = calloc(sizeof(struct trie_node), 1); if (!trie->root) { rc = EXIT_FAILURE; goto out; } trie->nodes_count++; err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs); if (err < 0) { log_error("failed to enumerate hwdb files: %s\n", strerror(-err)); rc = EXIT_FAILURE; goto out; } STRV_FOREACH(f, files) { log_debug("reading file '%s'", *f); import_file(udev, trie, *f); } strv_free(files); strbuf_complete(trie->strings); log_debug("=== trie in-memory ===\n"); log_debug("nodes: %8zu bytes (%8zu)\n", trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); log_debug("children arrays: %8zu bytes (%8zu)\n", trie->children_count * sizeof(struct trie_child_entry), trie->children_count); log_debug("values arrays: %8zu bytes (%8zu)\n", trie->values_count * sizeof(struct trie_value_entry), trie->values_count); log_debug("strings: %8zu bytes\n", trie->strings->len); log_debug("strings incoming: %8zu bytes (%8zu)\n", trie->strings->in_len, trie->strings->in_count); log_debug("strings dedup'ed: %8zu bytes (%8zu)\n", trie->strings->dedup_len, trie->strings->dedup_count); if (root) { if (asprintf(&udev_hwdb_path, "%s/%s", root, udev_hwdb_path) < 0) { rc = EXIT_FAILURE; goto out; } } mkdir_parents(udev_hwdb_path, 0755); err = trie_store(trie, udev_hwdb_path); if (root) { free(udev_hwdb_path); } if (err < 0) { log_error("Failure writing database %s: %s", udev_hwdb_path, strerror(-err)); rc = EXIT_FAILURE; } }
int main () { Trie *test_trie; DictRec *dict_p; TrieState *trie_root_state; TrieIterator *trie_it; Bool is_failed; msg_step ("Preparing trie"); test_trie = en_trie_new (); if (!test_trie) { fprintf (stderr, "Fail to create test trie\n"); goto err_trie_not_created; } /* store */ msg_step ("Adding data to trie"); for (dict_p = dict_src; dict_p->key; dict_p++) { if (!trie_store (test_trie, dict_p->key, dict_p->data)) { printf ("Failed to add key '%ls', data %d.\n", dict_p->key, dict_p->data); goto err_trie_created; } } /* iterate & check */ msg_step ("Iterating and checking trie contents"); trie_root_state = trie_root (test_trie); if (!trie_root_state) { printf ("Failed to get trie root state\n"); goto err_trie_created; } trie_it = trie_iterator_new (trie_root_state); if (!trie_it) { printf ("Failed to get trie iterator\n"); goto err_trie_root_created; } is_failed = FALSE; while (trie_iterator_next (trie_it)) { AlphaChar *key; TrieData key_data, src_data; key = trie_iterator_get_key (trie_it); if (!key) { printf ("Failed to get key from trie iterator\n"); is_failed = TRUE; continue; } key_data = trie_iterator_get_data (trie_it); if (TRIE_DATA_ERROR == key_data) { printf ("Failed to get data from trie iterator for key '%ls'\n", key); is_failed = TRUE; } /* mark entries found in trie */ src_data = dict_src_get_data (key); if (TRIE_DATA_ERROR == src_data) { printf ("Extra entry in trie: key '%ls', data %d.\n", key, key_data); is_failed = TRUE; } else if (src_data != key_data) { printf ("Data mismatch for: key '%ls', expected %d, got %d.\n", key, src_data, key_data); is_failed = TRUE; } else { dict_src_set_data (key, TRIE_DATA_READ); } free (key); } /* check for unmarked entries, (i.e. missed in trie) */ for (dict_p = dict_src; dict_p->key; dict_p++) { if (dict_p->data != TRIE_DATA_READ) { printf ("Entry missed in trie: key '%ls', data %d.\n", dict_p->key, dict_p->data); is_failed = TRUE; } } if (is_failed) { printf ("Errors found in trie iteration.\n"); goto err_trie_it_created; } trie_iterator_free (trie_it); trie_state_free (trie_root_state); trie_free (test_trie); return 0; err_trie_it_created: trie_iterator_free (trie_it); err_trie_root_created: trie_state_free (trie_root_state); err_trie_created: trie_free (test_trie); err_trie_not_created: return 1; }
int main (void) { Trie *test_trie; DictRec *dict_p; TrieData trie_data; Bool is_failed; int n_entries, n_dels, i; TrieState *trie_root_state; TrieIterator *trie_it; msg_step ("Preparing trie"); test_trie = en_trie_new (); if (!test_trie) { fprintf (stderr, "Fail to create test trie\n"); goto err_trie_not_created; } /* store */ msg_step ("Adding data to trie"); for (dict_p = dict_src; dict_p->key; dict_p++) { if (!trie_store (test_trie, dict_p->key, dict_p->data)) { printf ("Failed to add key '%ls', data %d.\n", (wchar_t *)dict_p->key, dict_p->data); goto err_trie_created; } } /* retrieve */ msg_step ("Retrieving data from trie"); is_failed = FALSE; for (dict_p = dict_src; dict_p->key; dict_p++) { if (!trie_retrieve (test_trie, dict_p->key, &trie_data)) { printf ("Failed to retrieve key '%ls'.\n", (wchar_t *)dict_p->key); is_failed = TRUE; } if (trie_data != dict_p->data) { printf ("Wrong data for key '%ls'; expected %d, got %d.\n", (wchar_t *)dict_p->key, dict_p->data, trie_data); is_failed = TRUE; } } if (is_failed) { printf ("Trie store/retrieval test failed.\n"); goto err_trie_created; } /* delete */ msg_step ("Deleting some entries from trie"); n_entries = dict_src_n_entries (); srand (time (NULL)); for (n_dels = n_entries/3 + 1; n_dels > 0; n_dels--) { /* pick an undeleted entry */ do { i = rand () % n_entries; } while (TRIE_DATA_READ == dict_src[i].data); printf ("Deleting '%ls'\n", (wchar_t *)dict_src[i].key); if (!trie_delete (test_trie, dict_src[i].key)) { printf ("Failed to delete '%ls'\n", (wchar_t *)dict_src[i].key); is_failed = TRUE; } dict_src[i].data = TRIE_DATA_READ; } if (is_failed) { printf ("Trie deletion test failed.\n"); goto err_trie_created; } /* retrieve */ msg_step ("Retrieving data from trie again after deletions"); for (dict_p = dict_src; dict_p->key; dict_p++) { /* skip deleted entries */ if (TRIE_DATA_READ == dict_p->data) continue; if (!trie_retrieve (test_trie, dict_p->key, &trie_data)) { printf ("Failed to retrieve key '%ls'.\n", (wchar_t *)dict_p->key); is_failed = TRUE; } if (trie_data != dict_p->data) { printf ("Wrong data for key '%ls'; expected %d, got %d.\n", (wchar_t *)dict_p->key, dict_p->data, trie_data); is_failed = TRUE; } } if (is_failed) { printf ("Trie retrival-after-deletion test failed.\n"); goto err_trie_created; } /* enumerate & check */ msg_step ("Iterating trie contents after deletions"); trie_root_state = trie_root (test_trie); if (!trie_root_state) { printf ("Failed to get trie root state\n"); goto err_trie_created; } trie_it = trie_iterator_new (trie_root_state); if (!trie_it) { printf ("Failed to get trie iterator\n"); goto err_trie_root_created; } while (trie_iterator_next (trie_it)) { AlphaChar *key; TrieData key_data, src_data; key = trie_iterator_get_key (trie_it); if (!key) { printf ("Failed to get key from trie iterator\n"); is_failed = TRUE; continue; } key_data = trie_iterator_get_data (trie_it); if (TRIE_DATA_ERROR == key_data) { printf ("Failed to get data from trie iterator for key '%ls'\n", (wchar_t *)key); is_failed = TRUE; } /* mark entries found in trie */ src_data = dict_src_get_data (key); if (TRIE_DATA_ERROR == src_data) { printf ("Extra entry in trie: key '%ls', data %d.\n", (wchar_t *)key, key_data); is_failed = TRUE; } else if (src_data != key_data) { printf ("Data mismatch for: key '%ls', expected %d, got %d.\n", (wchar_t *)key, src_data, key_data); is_failed = TRUE; } else { dict_src_set_data (key, TRIE_DATA_READ); } free (key); } /* check for unmarked entries, (i.e. missed in trie) */ for (dict_p = dict_src; dict_p->key; dict_p++) { if (dict_p->data != TRIE_DATA_READ) { printf ("Entry missed in trie: key '%ls', data %d.\n", (wchar_t *)dict_p->key, dict_p->data); is_failed = TRUE; } } if (is_failed) { printf ("Errors found in trie iteration after deletions.\n"); goto err_trie_it_created; } trie_iterator_free (trie_it); trie_state_free (trie_root_state); trie_free (test_trie); return 0; err_trie_it_created: trie_iterator_free (trie_it); err_trie_root_created: trie_state_free (trie_root_state); err_trie_created: trie_free (test_trie); err_trie_not_created: return 1; }
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { { "update", no_argument, NULL, 'u' }, { "test", required_argument, NULL, 't' }, { "root", required_argument, NULL, 'r' }, { "help", no_argument, NULL, 'h' }, {} }; const char *test = NULL; const char *root = ""; bool update = false; struct trie *trie = NULL; int err, c; int rc = EXIT_SUCCESS; while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0) switch(c) { case 'u': update = true; break; case 't': test = optarg; break; case 'r': root = optarg; break; case 'h': help(); return EXIT_SUCCESS; case '?': return EXIT_FAILURE; default: assert_not_reached("Unknown option"); } if (!update && !test) { log_error("Either --update or --test must be used"); return EXIT_FAILURE; } if (update) { char **files, **f; _cleanup_free_ char *hwdb_bin = UDEV_HWDB_BIN; trie = calloc(sizeof(struct trie), 1); if (!trie) { rc = EXIT_FAILURE; goto out; } /* string store */ trie->strings = strbuf_new(); if (!trie->strings) { rc = EXIT_FAILURE; goto out; } /* index */ trie->root = calloc(sizeof(struct trie_node), 1); if (!trie->root) { rc = EXIT_FAILURE; goto out; } trie->nodes_count++; err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs); if (err < 0) { log_error("failed to enumerate hwdb files: %s", strerror(-err)); rc = EXIT_FAILURE; goto out; } STRV_FOREACH(f, files) { log_debug("reading file '%s'", *f); import_file(udev, trie, *f); } strv_free(files); strbuf_complete(trie->strings); log_debug("=== trie in-memory ==="); log_debug("nodes: %8zu bytes (%8zu)", trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); log_debug("children arrays: %8zu bytes (%8zu)", trie->children_count * sizeof(struct trie_child_entry), trie->children_count); log_debug("values arrays: %8zu bytes (%8zu)", trie->values_count * sizeof(struct trie_value_entry), trie->values_count); log_debug("strings: %8zu bytes", trie->strings->len); log_debug("strings incoming: %8zu bytes (%8zu)", trie->strings->in_len, trie->strings->in_count); log_debug("strings dedup'ed: %8zu bytes (%8zu)", trie->strings->dedup_len, trie->strings->dedup_count); if (asprintf(&hwdb_bin, "%s/%s", root, hwdb_bin) < 0) { rc = EXIT_FAILURE; goto out; } mkdir_parents(hwdb_bin, 0755); err = trie_store(trie, hwdb_bin); if (err < 0) { log_error("Failure writing database %s: %s", hwdb_bin, strerror(-err)); rc = EXIT_FAILURE; } }