/** * raptor_avltree_add: * @tree: AVL Tree object * @p_data: pointer to data item * * add an item to an AVL Tree * * The item added becomes owned by the AVL Tree, and will be freed by * the free_handler argument given to raptor_new_avltree(). * * Return value: 0 on success, >0 if equivalent item exists (and the old element remains in the tree), <0 on failure */ int raptor_avltree_add(raptor_avltree* tree, void* p_data) { int rebalancing = FALSE; int rv; #if RAPTOR_DEBUG > 1 RAPTOR_AVLTREE_DEBUG1("Checking tree before adding\n"); raptor_avltree_check(tree); #endif rv = raptor_avltree_sprout(tree, NULL, &tree->root, p_data, &rebalancing); #if RAPTOR_DEBUG > 1 RAPTOR_AVLTREE_DEBUG1("Checking tree after adding\n"); raptor_avltree_check(tree); #endif return rv; }
/** * raptor_avltree_remove: * @tree: AVL Tree object * @p_data: pointer to data item * * Remove an item from an AVL Tree and return it * * The item removed is no longer owned by the AVL Tree and is * owned by the caller. * * Return value: object or NULL on failure or if not found */ void* raptor_avltree_remove(raptor_avltree* tree, void* p_data) { int rebalancing = FALSE; void* rdata; #if RAPTOR_DEBUG > 1 RAPTOR_AVLTREE_DEBUG1("Checking tree before removing\n"); raptor_avltree_dump(tree,stderr); raptor_avltree_check(tree); #endif rdata = raptor_avltree_delete_internal(tree, &tree->root, p_data, &rebalancing); if(rdata) tree->size--; #if RAPTOR_DEBUG > 1 RAPTOR_AVLTREE_DEBUG1("Checking tree after removing\n"); raptor_avltree_dump(tree,stderr); raptor_avltree_check(tree); #endif return rdata; }
/** * raptor_subject_add_property: * @subject: subject node to add to * @predicate: predicate node * @object: object node * * INTERNAL - Add predicate/object pair into properties array of a subject node. * * The subject node takes ownership of the predicate/object nodes. * On error, predicate/object are freed immediately. * * Return value: <0 on failure, >0 if pair is a duplicate and it was not added **/ int raptor_abbrev_subject_add_property(raptor_abbrev_subject* subject, raptor_abbrev_node* predicate, raptor_abbrev_node* object) { int err; raptor_abbrev_node** nodes; nodes=raptor_new_abbrev_po(predicate, object); if(!nodes) return -1; predicate->ref_count++; object->ref_count++; if(raptor_avltree_search(subject->properties, nodes)) { /* Already present - do not add a duplicate triple (s->[p o]) */ raptor_free_abbrev_po(nodes); return 1; } #if 0 fprintf(stderr, "Adding P,O "); raptor_print_abbrev_po(stderr, nodes); raptor_avltree_dump(subject->properties, stderr); #endif err = raptor_avltree_add(subject->properties, nodes); if(err) { raptor_free_abbrev_po(nodes); return -1; } #if 0 fprintf(stderr, "Result "); raptor_avltree_print(subject->properties, stderr); raptor_avltree_dump(subject->properties, stderr); raptor_avltree_check(subject->properties); fprintf(stderr, "\n\n"); #endif return 0; }
/* * raptor_subject_add_property: * @subject: subject node to add to * @predicate: predicate node * @object: object node * * Add predicate/object pair into properties array of a subject node. * The subject node takes ownership of the predicate/object nodes. * On error, predicate/object are freed immediately. * * Return value: non-0 on failure **/ int raptor_abbrev_subject_add_property(raptor_abbrev_subject* subject, raptor_abbrev_node* predicate, raptor_abbrev_node* object) { int err; raptor_abbrev_node** nodes; nodes=raptor_new_abbrev_po(predicate, object); if(!nodes) return 1; predicate->ref_count++; object->ref_count++; #if 0 fprintf(stderr, "Adding P,O "); raptor_print_abbrev_po(stderr, nodes); raptor_avltree_dump(subject->properties, stderr); #endif err = raptor_avltree_add(subject->properties, nodes); if(err) { raptor_free_abbrev_po(nodes); return err; } #if 0 fprintf(stderr, "Result "); raptor_avltree_print(subject->properties, stderr); raptor_avltree_dump(subject->properties, stderr); raptor_avltree_check(subject->properties); fprintf(stderr, "\n\n"); #endif return 0; }
int main(int argc, char *argv[]) { raptor_world *world; const char *program = raptor_basename(argv[0]); #define ITEM_COUNT 8 const char *items[ITEM_COUNT+1] = { "ron", "amy", "jen", "bij", "jib", "daj", "jim", "def", NULL }; #define DELETE_COUNT 2 const char *delete_items[DELETE_COUNT+1] = { "jen", "jim", NULL }; #define RESULT_COUNT (ITEM_COUNT-DELETE_COUNT) const char *results[RESULT_COUNT+1] = { "amy", "bij", "daj", "def", "jib", "ron", NULL}; raptor_avltree* tree; raptor_avltree_iterator* iter; visit_state vs; int i; world = raptor_new_world(); if(!world || raptor_world_open(world)) exit(1); tree = raptor_new_avltree(compare_strings, NULL, /* no free as they are static pointers above */ 0); if(!tree) { fprintf(stderr, "%s: Failed to create tree\n", program); exit(1); } for(i = 0; items[i]; i++) { int rc; void* node; #if RAPTOR_DEBUG > 1 fprintf(stderr, "%s: Adding tree item '%s'\n", program, items[i]); #endif rc = raptor_avltree_add(tree, (void*)items[i]); if(rc) { fprintf(stderr, "%s: Adding tree item %d '%s' failed, returning error %d\n", program, i, items[i], rc); exit(1); } #ifdef RAPTOR_DEBUG raptor_avltree_check(tree); #endif node = raptor_avltree_search(tree, (void*)items[i]); if(!node) { fprintf(stderr, "%s: Tree did NOT contain item %d '%s' as expected\n", program, i, items[i]); exit(1); } } #if RAPTOR_DEBUG > 1 fprintf(stderr, "%s: Printing tree\n", program); vs.fh = stderr; vs.count = 0; raptor_avltree_visit(tree, print_string, &vs); fprintf(stderr, "%s: Dumping tree\n", program); raptor_avltree_dump(tree, stderr); #endif for(i = 0; delete_items[i]; i++) { int rc; #if RAPTOR_DEBUG > 1 fprintf(stderr, "%s: Deleting tree item '%s'\n", program, delete_items[i]); #endif rc = raptor_avltree_delete(tree, (void*)delete_items[i]); if(!rc) { fprintf(stderr, "%s: Deleting tree item %d '%s' failed, returning error %d\n", program, i, delete_items[i], rc); exit(1); } #ifdef RAPTOR_DEBUG raptor_avltree_check(tree); #endif } #if RAPTOR_DEBUG > 1 fprintf(stderr, "%s: Walking tree forwards via iterator\n", program); #endif iter = raptor_new_avltree_iterator(tree, NULL, NULL, 1); for(i = 0; 1; i++) { const char* data = (const char*)raptor_avltree_iterator_get(iter); const char* result = results[i]; if((!data && data != result) || (data && strcmp(data, result))) { fprintf(stderr, "%3d: Forwards iterator expected '%s' but found '%s'\n", i, result, data); exit(1); } #if RAPTOR_DEBUG > 1 fprintf(stderr, "%3d: Got '%s'\n", i, data); #endif if(raptor_avltree_iterator_next(iter)) break; if(i > RESULT_COUNT) { fprintf(stderr, "Forward iterator did not end on result %i as expected\n", i); exit(1); } } raptor_free_avltree_iterator(iter); #if RAPTOR_DEBUG > 1 fprintf(stderr, "%s: Checking tree\n", program); #endif vs.count = 0; vs.results = results; vs.failed = 0; raptor_avltree_visit(tree, check_string, &vs); if(vs.failed) { fprintf(stderr, "%s: Checking tree failed\n", program); exit(1); } for(i = 0; results[i]; i++) { const char* result = results[i]; char* data = (char*)raptor_avltree_remove(tree, (void*)result); if(!data) { fprintf(stderr, "%s: remove %i failed at item '%s'\n", program, i, result); exit(1); } if(strcmp(data, result)) { fprintf(stderr, "%s: remove %i returned %s not %s as expected\n", program, i, data, result); exit(1); } } #if RAPTOR_DEBUG > 1 fprintf(stderr, "%s: Freeing tree\n", program); #endif raptor_free_avltree(tree); raptor_free_world(world); /* keep gcc -Wall happy */ return(0); }