falcon_object_t *falcon_cache_get(falcon_cache_t *cache, const gchar *name) { trie_node_t *node = NULL; g_return_val_if_fail(cache, NULL); g_return_val_if_fail(name, NULL); g_mutex_lock(cache->lock); node = trie_find(cache->objects, name); g_mutex_unlock(cache->lock); return trie_data(node); }
void falcon_cache_foreach_child(falcon_cache_t *cache, const gchar *name, GFunc func, gpointer userdata) { trie_node_t *node = NULL; trie_node_t *next = NULL; falcon_object_t *data = NULL; g_return_if_fail(cache); g_return_if_fail(func); g_mutex_lock(cache->lock); node = trie_find(cache->objects, name); next = trie_child(node); while (next) { if ((data = trie_data(next))) func(data, userdata); next = trie_next(next); } if ((data = trie_data(node))) func(data, userdata); g_mutex_unlock(cache->lock); }
int main(void) { static struct word word1 = { .data = (uint8_t *)"aaa", .size = 4, .value = (void *)0xA}; static struct word word2 = { .data = (uint8_t *)"aba", .size = 4, .value = (void *)0xB}; struct trie *obj = trie_new(NULL, dealloc); assert(obj); void *data; bool ret; ret = trie_insert(obj, word1.data, word1.size, word1.value, &data); assert(ret); assert(data == NULL); // check the first insertion ret = trie_at(obj, word1.data, word1.size, &data); assert(ret); assert(data == word1.value); ret = trie_insert(obj, word2.data, word2.size, word2.value, &data); assert(ret); assert(data == NULL); // check all after all insertions ret = trie_at(obj, word1.data, word1.size, &data); assert(ret); assert(data == word1.value); ret = trie_at(obj, word2.data, word2.size, &data); assert(ret); assert(data == word2.value); for (struct trie_node *i = trie_begin(obj); i; i = trie_next_delete(obj, i)) { char *str = NULL; if (trie_data(i, (void *)&str)) printf("trie next: 0x%x\n", (unsigned int)str); else printf("trie next failed!\n"); } trie_delete(&obj); assert(obj == NULL); return 0; }
static void falcon_cache_recursive_foreach_descendant(const trie_node_t *node, GFunc func, gpointer udata) { falcon_object_t *data = NULL; while (node) { if (trie_child(node)) falcon_cache_recursive_foreach_descendant(trie_child(node), func, udata); if ((data = trie_data(node))) func(data, udata); node = trie_next(node); } }
void falcon_object_save(trie_node_t *node, void *userdata) { const falcon_object_t *object = (const falcon_object_t *)trie_data(node); int fd = GPOINTER_TO_INT(userdata); guint16 len = strlen(object->name); guint16 len_be = GUINT16_TO_BE(len); guint64 size = GUINT64_TO_BE(object->size); guint64 time = GUINT64_TO_BE(object->time); guint32 mode = GUINT32_TO_BE(object->mode); if (write(fd, &len_be, 2) == -1 || write(fd, object->name, len) == -1 || write(fd, &size, 8) == -1 || write(fd, &time, 8) == -1 || write(fd, &mode, 4) == -1 || write(fd, &(object->watch), 1) == -1) g_critical(_("Failed to save object \"%s\": %s"), object->name, g_strerror(errno)); }
void falcon_cache_foreach_descendant(falcon_cache_t *cache, const gchar *name, GFunc func, gpointer userdata) { trie_node_t *node = NULL; falcon_object_t *data = NULL; g_return_if_fail(cache); g_return_if_fail(func); g_mutex_lock(cache->lock); node = trie_find(cache->objects, name); falcon_cache_recursive_foreach_descendant(trie_child(node), func, userdata); if ((data = trie_data(node))) func(data, userdata); g_mutex_unlock(cache->lock); }
gboolean falcon_cache_add(falcon_cache_t *cache, falcon_object_t *object) { trie_node_t *old_node = NULL; falcon_object_t *old = NULL; falcon_object_t *dup = falcon_object_copy(object); g_return_val_if_fail(cache, FALSE); g_return_val_if_fail(object, FALSE); g_mutex_lock(cache->lock); old_node = trie_find(cache->objects, falcon_object_get_name(dup)); if (old_node && (old = trie_data(old_node))) { falcon_object_free(old); trie_set_data(old_node, dup); } else { trie_add(cache->objects, falcon_object_get_name(dup), dup); cache->count++; } g_mutex_unlock(cache->lock); return TRUE; }