COMPS_HSList * comps_rtree_values(COMPS_RTree * rt) { COMPS_HSList *ret, *tmplist, *tmp_subnodes; COMPS_HSListItem *it, *firstit; ret = comps_hslist_create(); comps_hslist_init(ret, NULL, NULL, NULL); tmplist = comps_hslist_create(); comps_hslist_init(tmplist, NULL, NULL, NULL); comps_hslist_append(tmplist, rt->subnodes, 0); while (tmplist->first != NULL) { it = tmplist->first; firstit = it; comps_hslist_remove(tmplist, firstit); tmp_subnodes = (COMPS_HSList*)it->data; for (it = tmp_subnodes->first; it != NULL; it=it->next) { if (((COMPS_RTreeData*)it->data)->subnodes->first) { comps_hslist_append(tmplist, ((COMPS_RTreeData*)it->data)->subnodes, 0); } if (((COMPS_RTreeData*)it->data)->data != NULL) { comps_hslist_append(ret, ((COMPS_RTreeData*)it->data)->data, 0); } } free(firstit); } comps_hslist_destroy(&tmplist); return ret; }
COMPS_RTree * comps_rtree_clone(COMPS_RTree *rt) { COMPS_HSList *to_clone, *tmplist, *new_subnodes; COMPS_RTree *ret; COMPS_HSListItem *it, *it2; COMPS_RTreeData *rtdata;//, *rtdata2; void *new_data; if (!rt) return NULL; to_clone = comps_hslist_create(); comps_hslist_init(to_clone, NULL, NULL, NULL); ret = comps_rtree_create(rt->data_constructor, rt->data_cloner, rt->data_destructor); for (it = rt->subnodes->first; it != NULL; it = it->next) { rtdata = comps_rtree_data_create(rt, ((COMPS_RTreeData*)it->data)->key, NULL); new_data = rt->data_cloner(((COMPS_RTreeData*)it->data)->data); comps_hslist_destroy(&rtdata->subnodes); rtdata->subnodes = ((COMPS_RTreeData*)it->data)->subnodes; rtdata->data = new_data; comps_hslist_append(ret->subnodes, rtdata, 0); comps_hslist_append(to_clone, rtdata, 0); } while (to_clone->first) { it2 = to_clone->first; tmplist = ((COMPS_RTreeData*)it2->data)->subnodes; comps_hslist_remove(to_clone, to_clone->first); new_subnodes = comps_hslist_create(); comps_hslist_init(new_subnodes, NULL, NULL, &comps_rtree_data_destroy_v); for (it = tmplist->first; it != NULL; it = it->next) { rtdata = comps_rtree_data_create(rt, ((COMPS_RTreeData*)it->data)->key, NULL); if (((COMPS_RTreeData*)it->data)->data != NULL) new_data = rt->data_cloner(((COMPS_RTreeData*)it->data)->data); else new_data = NULL; comps_hslist_destroy(&rtdata->subnodes); rtdata->subnodes = ((COMPS_RTreeData*)it->data)->subnodes; rtdata->data = new_data; comps_hslist_append(new_subnodes, rtdata, 0); comps_hslist_append(to_clone, rtdata, 0); } ((COMPS_RTreeData*)it2->data)->subnodes = new_subnodes; free(it2); } comps_hslist_destroy(&to_clone); return ret; }
void comps_objrtree_copy(COMPS_ObjRTree *rt1, COMPS_ObjRTree *rt2) { COMPS_HSList *to_clone, *tmplist, *new_subnodes; COMPS_HSListItem *it, *it2; COMPS_ObjRTreeData *rtdata; COMPS_Object *new_data; rt1->subnodes = comps_hslist_create(); comps_hslist_init(rt1->subnodes, NULL, NULL, &comps_objrtree_data_destroy_v); if (rt1->subnodes == NULL) { COMPS_OBJECT_DESTROY(rt1); return; } rt1->len = 0; to_clone = comps_hslist_create(); comps_hslist_init(to_clone, NULL, NULL, NULL); for (it = rt2->subnodes->first; it != NULL; it = it->next) { rtdata = comps_objrtree_data_create( ((COMPS_ObjRTreeData*)it->data)->key, NULL); if (((COMPS_ObjRTreeData*)it->data)->data != NULL) new_data = comps_object_copy(((COMPS_ObjRTreeData*)it->data)->data); else new_data = NULL; comps_hslist_destroy(&rtdata->subnodes); rtdata->subnodes = ((COMPS_ObjRTreeData*)it->data)->subnodes; rtdata->data = new_data; comps_hslist_append(rt1->subnodes, rtdata, 0); comps_hslist_append(to_clone, rtdata, 0); } while (to_clone->first) { it2 = to_clone->first; tmplist = ((COMPS_ObjRTreeData*)it2->data)->subnodes; comps_hslist_remove(to_clone, to_clone->first); new_subnodes = comps_hslist_create(); comps_hslist_init(new_subnodes, NULL, NULL, &comps_objrtree_data_destroy_v); for (it = tmplist->first; it != NULL; it = it->next) { rtdata = comps_objrtree_data_create( ((COMPS_ObjRTreeData*)it->data)->key, NULL); if (((COMPS_ObjRTreeData*)it->data)->data != NULL) new_data = comps_object_copy(((COMPS_ObjRTreeData*)it->data)->data); else new_data = NULL; comps_hslist_destroy(&rtdata->subnodes); rtdata->subnodes = ((COMPS_ObjRTreeData*)it->data)->subnodes; rtdata->data = new_data; comps_hslist_append(new_subnodes, rtdata, 0); comps_hslist_append(to_clone, rtdata, 0); } ((COMPS_ObjRTreeData*)it2->data)->subnodes = new_subnodes; free(it2); } comps_hslist_destroy(&to_clone); }
COMPS_ObjMRTree * comps_objmrtree_clone(COMPS_ObjMRTree * rt) { COMPS_HSList * to_clone, *tmplist, *new_subnodes; COMPS_ObjMRTree * ret; COMPS_HSListItem *it, *it2; COMPS_ObjMRTreeData *rtdata; COMPS_ObjList *new_data_list; to_clone = comps_hslist_create(); comps_hslist_init(to_clone, NULL, NULL, NULL); ret = (COMPS_ObjMRTree*)comps_object_create(&COMPS_ObjMRTree_ObjInfo, NULL); for (it = rt->subnodes->first; it != NULL; it = it->next) { rtdata = comps_objmrtree_data_create( ((COMPS_ObjMRTreeData*)it->data)->key, NULL); new_data_list = (COMPS_ObjList*) COMPS_OBJECT_COPY(((COMPS_ObjMRTreeData*)it->data)->data); COMPS_OBJECT_DESTROY(&rtdata->data); comps_hslist_destroy(&rtdata->subnodes); rtdata->subnodes = ((COMPS_ObjMRTreeData*)it->data)->subnodes; rtdata->data = new_data_list; comps_hslist_append(ret->subnodes, rtdata, 0); comps_hslist_append(to_clone, rtdata, 0); } while (to_clone->first) { it2 = to_clone->first; tmplist = ((COMPS_ObjMRTreeData*)it2->data)->subnodes; comps_hslist_remove(to_clone, to_clone->first); new_subnodes = comps_hslist_create(); comps_hslist_init(new_subnodes, NULL, NULL, &comps_objmrtree_data_destroy_v); for (it = tmplist->first; it != NULL; it = it->next) { rtdata = comps_objmrtree_data_create( ((COMPS_ObjMRTreeData*)it->data)->key, NULL); new_data_list = (COMPS_ObjList*) COMPS_OBJECT_COPY(((COMPS_ObjMRTreeData*)it->data)->data); comps_hslist_destroy(&rtdata->subnodes); COMPS_OBJECT_DESTROY(rtdata->data); rtdata->subnodes = ((COMPS_ObjMRTreeData*)it->data)->subnodes; rtdata->data = new_data_list; comps_hslist_append(new_subnodes, rtdata, 0); comps_hslist_append(to_clone, rtdata, 0); } ((COMPS_ObjMRTreeData*)it2->data)->subnodes = new_subnodes; free(it2); } ret->len = rt->len; comps_hslist_destroy(&to_clone); return ret; }
void comps_mrtree_values_walk(COMPS_MRTree * rt, void* udata, void (*walk_f)(void*, void*)) { COMPS_HSList *tmplist, *tmp_subnodes; COMPS_HSListItem *it, *it2; tmplist = comps_hslist_create(); comps_hslist_init(tmplist, NULL, NULL, NULL); comps_hslist_append(tmplist, rt->subnodes, 0); while (tmplist->first != NULL) { it = tmplist->first; comps_hslist_remove(tmplist, tmplist->first); tmp_subnodes = (COMPS_HSList*)it->data; free(it); for (it = tmp_subnodes->first; it != NULL; it=it->next) { if (((COMPS_MRTreeData*)it->data)->subnodes->first) { comps_hslist_append(tmplist, ((COMPS_MRTreeData*)it->data)->subnodes, 0); } for (it2 = (COMPS_HSListItem*)((COMPS_MRTreeData*)it->data)->data->first; it2 != NULL; it2 = it2->next) { walk_f(udata, it2->data); } } } comps_hslist_destroy(&tmplist); }
static void comps_objrtree_create(COMPS_ObjRTree *rtree, COMPS_Object **args) { (void)args; rtree->subnodes = comps_hslist_create(); comps_hslist_init(rtree->subnodes, NULL, NULL, &comps_objrtree_data_destroy_v); if (rtree->subnodes == NULL) { COMPS_OBJECT_DESTROY(rtree); return; } rtree->len = 0; }
void comps_set_init(COMPS_Set * set, void* (*data_constructor)(void*), void* (*data_cloner)(void*), void (*data_destructor)(void*), char (*eqf)(void*, void*)) { if (set == NULL) return; set->data_constructor = data_constructor; set->data_destructor = data_destructor; set->data_cloner = data_cloner; set->eqf = eqf; comps_hslist_init(set->data, data_constructor, data_cloner, data_destructor); }
COMPS_HSList* comps_hslist_clone(COMPS_HSList * hslist) { COMPS_HSList *ret; COMPS_HSListItem *it; ret = comps_hslist_create(); comps_hslist_init(ret, hslist->data_constructor, hslist->data_cloner, hslist->data_destructor); for (it = hslist->first; it != NULL; it = it->next) { comps_hslist_append(ret, hslist->data_cloner(it->data), 0); } return ret; }
COMPS_MRTreeData * comps_mrtree_data_create_n(COMPS_MRTree * tree, char * key, size_t keylen, void * data) { COMPS_MRTreeData * rtd; if ((rtd = malloc(sizeof(*rtd))) == NULL) return NULL; if ((rtd->key = malloc(sizeof(char) * (keylen+1))) == NULL) { free(rtd); return NULL; } memcpy(rtd->key, key, sizeof(char)*keylen); rtd->key[keylen] = 0; rtd->is_leaf = 1; rtd->data = comps_hslist_create(); comps_hslist_init(rtd->data, NULL, tree->data_cloner, tree->data_destructor); if (data) comps_hslist_append(rtd->data, data, 0); rtd->subnodes = comps_hslist_create(); comps_hslist_init(rtd->subnodes, NULL, NULL, &comps_mrtree_data_destroy_v); return rtd; }
COMPS_RTree * comps_rtree_create(void* (*data_constructor)(void*), void* (*data_cloner)(void*), void (*data_destructor)(void*)) { COMPS_RTree *ret; if ((ret = malloc(sizeof(COMPS_RTree))) == NULL) return NULL; ret->subnodes = comps_hslist_create(); comps_hslist_init(ret->subnodes, NULL, NULL, &comps_rtree_data_destroy_v); if (ret->subnodes == NULL) { free(ret); return NULL; } ret->data_constructor = data_constructor; ret->data_cloner = data_cloner; ret->data_destructor = data_destructor; return ret; }
inline COMPS_ObjRTreeData * __comps_objrtree_data_create(char *key, size_t keylen, COMPS_Object *data) { COMPS_ObjRTreeData * rtd; if ((rtd = malloc(sizeof(*rtd))) == NULL) return NULL; if ((rtd->key = malloc(sizeof(char) * (keylen+1))) == NULL) { free(rtd); return NULL; } memcpy(rtd->key, key, sizeof(char)*keylen); rtd->key[keylen] = 0; rtd->data = data; if (data != NULL) { rtd->is_leaf = 1; } rtd->subnodes = comps_hslist_create(); comps_hslist_init(rtd->subnodes, NULL, NULL, &comps_objrtree_data_destroy_v); return rtd; }
inline COMPS_RTreeData * __comps_rtree_data_create(COMPS_RTree *rt, char *key, unsigned int keylen, void *data){ COMPS_RTreeData * rtd; if ((rtd = malloc(sizeof(*rtd))) == NULL) return NULL; if ((rtd->key = malloc(sizeof(char) * (keylen+1))) == NULL) { free(rtd); return NULL; } memcpy(rtd->key, key, sizeof(char)*keylen); rtd->key[keylen] = 0; rtd->data = data; if (data != NULL) { rtd->is_leaf = 1; } rtd->data_destructor = &rt->data_destructor; rtd->subnodes = comps_hslist_create(); comps_hslist_init(rtd->subnodes, NULL, NULL, &comps_rtree_data_destroy_v); return rtd; }
static COMPS_ObjMRTreeData * __comps_objmrtree_data_create(char * key, unsigned int keylen, COMPS_Object *data) { COMPS_ObjMRTreeData * rtd; if ((rtd = malloc(sizeof(*rtd))) == NULL) return NULL; if ((rtd->key = malloc(sizeof(char) * (keylen+1))) == NULL) { free(rtd); return NULL; } memcpy(rtd->key, key, sizeof(char)*keylen); rtd->key[keylen] = '\0'; rtd->is_leaf = 1; rtd->data = (COMPS_ObjList*)comps_object_create(&COMPS_ObjList_ObjInfo, NULL); if (data) comps_objlist_append_x(rtd->data, data); rtd->subnodes = comps_hslist_create(); comps_hslist_init(rtd->subnodes, NULL, NULL, &comps_objmrtree_data_destroy_v); return rtd; }
inline COMPS_HSList* __comps_rtree_all(COMPS_RTree * rt, char pairorkey) { COMPS_HSList *tmplist, *tmp_subnodes, *ret; COMPS_HSListItem *it; struct Pair { COMPS_HSList * subnodes; char * key; char added; } *pair, *parent_pair; COMPS_RTreePair *rtpair; pair = malloc(sizeof(struct Pair)); pair->subnodes = rt->subnodes; pair->key = NULL; pair->added = 0; tmplist = comps_hslist_create(); comps_hslist_init(tmplist, NULL, NULL, &free); ret = comps_hslist_create(); if (pairorkey == 1) comps_hslist_init(ret, NULL, NULL, &free); else comps_hslist_init(ret, NULL, NULL, &comps_rtree_pair_destroy_v); comps_hslist_append(tmplist, pair, 0); while (tmplist->first != NULL) { it = tmplist->first; comps_hslist_remove(tmplist, tmplist->first); tmp_subnodes = ((struct Pair*)it->data)->subnodes; parent_pair = (struct Pair*) it->data; //printf("subkey:%s\n", ((struct Pair*)it->data)->key); free(it); //pair->added = 0; for (it = tmp_subnodes->first; it != NULL; it=it->next) { pair = malloc(sizeof(struct Pair)); pair->subnodes = ((COMPS_RTreeData*)it->data)->subnodes; pair->added = 0; if (parent_pair->key != NULL) { pair->key = malloc(sizeof(char) * (strlen(((COMPS_RTreeData*)it->data)->key) + strlen(parent_pair->key) + 1)); memcpy(pair->key, parent_pair->key, sizeof(char) * strlen(parent_pair->key)); memcpy(pair->key+strlen(parent_pair->key), ((COMPS_RTreeData*)it->data)->key, sizeof(char)*(strlen(((COMPS_RTreeData*)it->data)->key)+1)); } else { pair->key = malloc(sizeof(char)* (strlen(((COMPS_RTreeData*)it->data)->key) + 1)); memcpy(pair->key, ((COMPS_RTreeData*)it->data)->key, sizeof(char)*(strlen(((COMPS_RTreeData*)it->data)->key)+1)); } //printf("%s|\n", pair->key); /* current node has data */ if (((COMPS_RTreeData*)it->data)->data != NULL) { //printf("data not null for |%s|\n", pair->key); if (pairorkey == 1) { comps_hslist_append(ret, pair->key, 0); } else { rtpair = malloc(sizeof(COMPS_RTreePair)); rtpair->key = pair->key; rtpair->data = ((COMPS_RTreeData*)it->data)->data; comps_hslist_append(ret, rtpair, 0); } pair->added = 1; if (((COMPS_RTreeData*)it->data)->subnodes->first != NULL) { // printf("subnodes found\b"); comps_hslist_append(tmplist, pair, 0); } else { free(pair); } /* current node hasn't data */ } else { //printf("no data\n"); if (((COMPS_RTreeData*)it->data)->subnodes->first) { comps_hslist_append(tmplist, pair, 0); //added = 1; } else { free(pair->key); free(pair); } } } if (parent_pair->added == 0) free(parent_pair->key); free(parent_pair); } comps_hslist_destroy(&tmplist); return ret; }
void comps_rtree_unset(COMPS_RTree * rt, const char * key) { COMPS_HSList * subnodes; COMPS_HSListItem * it; COMPS_RTreeData * rtdata; unsigned int offset, len, x; char found, ended; COMPS_HSList * path; struct Relation { COMPS_HSList * parent_nodes; COMPS_HSListItem * child_it; } *relation; path = comps_hslist_create(); comps_hslist_init(path, NULL, NULL, &free); len = strlen(key); offset = 0; subnodes = rt->subnodes; while (offset != len) { found = 0; for (it = subnodes->first; it != NULL; it=it->next) { if (((COMPS_RTreeData*)it->data)->key[0] == key[offset]) { found = 1; break; } } if (!found) return; rtdata = (COMPS_RTreeData*)it->data; for (x=1; ;x++) { ended=0; if (rtdata->key[x] == 0) ended += 1; if (x == len - offset) ended += 2; if (ended != 0) break; if (key[offset+x] != rtdata->key[x]) break; } if (ended == 3) { /* remove node from tree only if there's no descendant*/ if (rtdata->subnodes->last == NULL) { printf("removing all\n"); comps_hslist_remove(subnodes, it); comps_rtree_data_destroy(rtdata); free(it); } else if (rtdata->data_destructor != NULL) { printf("removing data only\n"); (*rtdata->data_destructor)(rtdata->data); rtdata->is_leaf = 0; rtdata->data = NULL; } if (path->last == NULL) { comps_hslist_destroy(&path); return; } rtdata = (COMPS_RTreeData*) ((struct Relation*)path->last->data)->child_it->data; /*remove all predecessor of deleted node (recursive) with no childs*/ while (rtdata->subnodes->last == NULL) { printf("removing '%s'\n", rtdata->key); comps_rtree_data_destroy(rtdata); comps_hslist_remove( ((struct Relation*)path->last->data)->parent_nodes, ((struct Relation*)path->last->data)->child_it); free(((struct Relation*)path->last->data)->child_it); it = path->last; comps_hslist_remove(path, path->last); free(it); rtdata = (COMPS_RTreeData*) ((struct Relation*)path->last->data)->child_it->data; } comps_hslist_destroy(&path); return; } else if (ended == 1) offset+=x; else return; if ((relation = malloc(sizeof(struct Relation))) == NULL) { comps_hslist_destroy(&path); return; } subnodes = ((COMPS_RTreeData*)it->data)->subnodes; relation->parent_nodes = subnodes; relation->child_it = it; comps_hslist_append(path, (void*)relation, 0); } comps_hslist_destroy(&path); return; }
COMPS_HSList* comps_mrtree_keys(COMPS_MRTree * rt) { COMPS_HSList *tmplist, *tmp_subnodes, *ret; COMPS_HSListItem *it; struct Pair { COMPS_HSList * subnodes; char * key; char added; } *pair, *parent_pair; pair = malloc(sizeof(struct Pair)); pair->subnodes = rt->subnodes; pair->key = NULL; pair->added = 0; tmplist = comps_hslist_create(); comps_hslist_init(tmplist, NULL, NULL, &free); ret = comps_hslist_create(); comps_hslist_init(ret, NULL, NULL, &free); comps_hslist_append(tmplist, pair, 0); while (tmplist->first != NULL) { it = tmplist->first; comps_hslist_remove(tmplist, tmplist->first); tmp_subnodes = ((struct Pair*)it->data)->subnodes; parent_pair = (struct Pair*) it->data; free(it); for (it = tmp_subnodes->first; it != NULL; it=it->next) { pair = malloc(sizeof(struct Pair)); pair->subnodes = ((COMPS_MRTreeData*)it->data)->subnodes; pair->added = 0; if (parent_pair->key != NULL) { pair->key = malloc(sizeof(char) * (strlen(((COMPS_MRTreeData*)it->data)->key) + strlen(parent_pair->key) + 1)); memcpy(pair->key, parent_pair->key, sizeof(char) * strlen(parent_pair->key)); memcpy(pair->key+strlen(parent_pair->key), ((COMPS_MRTreeData*)it->data)->key, sizeof(char)*(strlen(((COMPS_MRTreeData*)it->data)->key)+1)); } else { pair->key = malloc(sizeof(char)* (strlen(((COMPS_MRTreeData*)it->data)->key) + 1)); memcpy(pair->key, ((COMPS_MRTreeData*)it->data)->key, sizeof(char)*(strlen(((COMPS_MRTreeData*)it->data)->key)+1)); } /* current node has data */ if (((COMPS_MRTreeData*)it->data)->data->first != NULL) { //printf("data not null for |%s|\n", pair->key); comps_hslist_append(ret, pair->key, 0); pair->added = 1; if (((COMPS_MRTreeData*)it->data)->subnodes->first != NULL) { // printf("subnodes found\b"); comps_hslist_append(tmplist, pair, 0); } else { free(pair); } /* current node hasn't data */ } else { if (((COMPS_MRTreeData*)it->data)->subnodes->first) { comps_hslist_append(tmplist, pair, 0); } else { free(pair->key); free(pair); } } } if (parent_pair->added == 0) free(parent_pair->key); free(parent_pair); } comps_hslist_destroy(&tmplist); return ret; }
void comps_objrtree_unite(COMPS_ObjRTree *rt1, COMPS_ObjRTree *rt2) { COMPS_HSList *tmplist, *tmp_subnodes; COMPS_HSListItem *it; struct Pair { COMPS_HSList * subnodes; char * key; char added; } *pair, *parent_pair; pair = malloc(sizeof(struct Pair)); pair->subnodes = rt2->subnodes; pair->key = NULL; tmplist = comps_hslist_create(); comps_hslist_init(tmplist, NULL, NULL, &free); comps_hslist_append(tmplist, pair, 0); while (tmplist->first != NULL) { it = tmplist->first; comps_hslist_remove(tmplist, tmplist->first); tmp_subnodes = ((struct Pair*)it->data)->subnodes; parent_pair = (struct Pair*) it->data; //printf("key-part:%s\n", parent_pair->key); free(it); //pair->added = 0; for (it = tmp_subnodes->first; it != NULL; it=it->next) { pair = malloc(sizeof(struct Pair)); pair->subnodes = ((COMPS_ObjRTreeData*)it->data)->subnodes; if (parent_pair->key != NULL) { pair->key = malloc(sizeof(char) * (strlen(((COMPS_ObjRTreeData*)it->data)->key) + strlen(parent_pair->key) + 1)); memcpy(pair->key, parent_pair->key, sizeof(char) * strlen(parent_pair->key)); memcpy(pair->key + strlen(parent_pair->key), ((COMPS_ObjRTreeData*)it->data)->key, sizeof(char)*(strlen(((COMPS_ObjRTreeData*)it->data)->key)+1)); } else { pair->key = malloc(sizeof(char)* (strlen(((COMPS_ObjRTreeData*)it->data)->key) +1)); memcpy(pair->key, ((COMPS_ObjRTreeData*)it->data)->key, sizeof(char)*(strlen(((COMPS_ObjRTreeData*)it->data)->key)+1)); } /* current node has data */ if (((COMPS_ObjRTreeData*)it->data)->data != NULL) { comps_objrtree_set(rt1, pair->key, (((COMPS_ObjRTreeData*)it->data)->data)); } if (((COMPS_ObjRTreeData*)it->data)->subnodes->first) { comps_hslist_append(tmplist, pair, 0); } else { free(pair->key); free(pair); } } free(parent_pair->key); free(parent_pair); } comps_hslist_destroy(&tmplist); }
inline COMPS_HSList* __comps_objrtree_all(COMPS_ObjRTree * rt, char keyvalpair) { COMPS_HSList *to_process, *ret; COMPS_HSListItem *hsit, *oldit; size_t x; struct Pair { char *key; void *data; COMPS_HSList *subnodes; } *pair, *current_pair=NULL;//, *oldpair=NULL; COMPS_ObjRTreePair *rtpair; to_process = comps_hslist_create(); comps_hslist_init(to_process, NULL, NULL, &free); ret = comps_hslist_create(); if (keyvalpair == 0) comps_hslist_init(ret, NULL, NULL, &free); else if (keyvalpair == 1) comps_hslist_init(ret, NULL, NULL, NULL); else comps_hslist_init(ret, NULL, NULL, &comps_objrtree_pair_destroy_v); for (hsit = rt->subnodes->first; hsit != NULL; hsit = hsit->next) { pair = malloc(sizeof(struct Pair)); pair->key = __comps_strcpy(((COMPS_ObjRTreeData*)hsit->data)->key); pair->data = ((COMPS_ObjRTreeData*)hsit->data)->data; pair->subnodes = ((COMPS_ObjRTreeData*)hsit->data)->subnodes; comps_hslist_append(to_process, pair, 0); } while (to_process->first) { //oldpair = current_pair; current_pair = to_process->first->data; oldit = to_process->first; comps_hslist_remove(to_process, to_process->first); if (current_pair->data) { if (keyvalpair == 0) { comps_hslist_append(ret, __comps_strcpy(current_pair->key), 0); } else if (keyvalpair == 1) { comps_hslist_append(ret, current_pair->data, 0); } else { rtpair = malloc(sizeof(COMPS_ObjRTreePair)); rtpair->key = __comps_strcpy(current_pair->key); rtpair->data = current_pair->data; comps_hslist_append(ret, rtpair, 0); } } for (hsit = current_pair->subnodes->first, x = 0; hsit != NULL; hsit = hsit->next, x++) { pair = malloc(sizeof(struct Pair)); pair->key = __comps_strcat(current_pair->key, ((COMPS_ObjRTreeData*)hsit->data)->key); pair->data = ((COMPS_ObjRTreeData*)hsit->data)->data; pair->subnodes = ((COMPS_ObjRTreeData*)hsit->data)->subnodes; comps_hslist_insert_at(to_process, x, pair, 0); } free(current_pair->key); free(current_pair); free(oldit); } comps_hslist_destroy(&to_process); return ret; }
void __comps_objrtree_set(COMPS_ObjRTree *rt, char *key, size_t len, COMPS_Object *ndata) { COMPS_HSListItem *it, *lesser; COMPS_HSList *subnodes; COMPS_ObjRTreeData *rtd; static COMPS_ObjRTreeData *rtdata; size_t _len, offset=0; unsigned x, found = 0; char ended; //len = strlen(key); if (rt->subnodes == NULL) return; subnodes = rt->subnodes; while (offset != len) { found = 0; lesser = NULL; for (it = subnodes->first; it != NULL; it=it->next) { if (((COMPS_ObjRTreeData*)it->data)->key[0] == key[offset]) { found = 1; break; } else if (((COMPS_ObjRTreeData*)it->data)->key[0] < key[offset]) { lesser = it; } } if (!found) { // not found in subnodes; create new subnode rtd = comps_objrtree_data_create_n(key+offset, len-offset, ndata); if (!lesser) { comps_hslist_prepend(subnodes, rtd, 0); } else { comps_hslist_insert_after(subnodes, lesser, rtd, 0); } rt->len++; return; } else { rtdata = (COMPS_ObjRTreeData*)it->data; ended = 0; for (x=1; ; x++) { if (rtdata->key[x] == 0) ended += 1; if (x == len - offset) ended += 2; if (ended != 0) break; if (key[offset+x] != rtdata->key[x]) break; } if (ended == 3) { //keys equals; data replacement comps_object_destroy(rtdata->data); rtdata->data = ndata; return; } else if (ended == 2) { //global key ends first; make global leaf //printf("ended2\n"); comps_hslist_remove(subnodes, it); it->next = NULL; rtd = comps_objrtree_data_create_n(key+offset, len-offset, ndata); comps_hslist_append(subnodes, rtd, 0); ((COMPS_ObjRTreeData*)subnodes->last->data)->subnodes->last = it; ((COMPS_ObjRTreeData*)subnodes->last->data)->subnodes->first = it; _len = len - offset; memmove(rtdata->key,rtdata->key+_len, strlen(rtdata->key) - _len); rtdata->key[strlen(rtdata->key) - _len] = 0; rtdata->key = realloc(rtdata->key, sizeof(char)* (strlen(rtdata->key)+1)); rt->len++; return; } else if (ended == 1) { //local key ends first; go deeper subnodes = rtdata->subnodes; offset += x; } else { COMPS_Object *tmpdata = rtdata->data; COMPS_HSList *tmphslist = rtdata->subnodes; //tmpch = rtdata->key[x]; // split mutual key rtdata->subnodes = comps_hslist_create(); comps_hslist_init(rtdata->subnodes, NULL, NULL, &comps_objrtree_data_destroy_v); int cmpret = strcmp(key+offset+x, rtdata->key+x); rtdata->data = NULL; if (cmpret > 0) { rtd = comps_objrtree_data_create(rtdata->key+x, tmpdata); comps_hslist_destroy(&rtd->subnodes); rtd->subnodes = tmphslist; comps_hslist_append(rtdata->subnodes,rtd, 0); rtd = comps_objrtree_data_create(key+offset+x, ndata); comps_hslist_append(rtdata->subnodes, rtd, 0); } else { rtd = comps_objrtree_data_create(key+offset+x, ndata); comps_hslist_append(rtdata->subnodes, rtd, 0); rtd = comps_objrtree_data_create(rtdata->key+x, tmpdata); comps_hslist_destroy(&rtd->subnodes); rtd->subnodes = tmphslist; comps_hslist_append(rtdata->subnodes, rtd, 0); } rtdata->key = realloc(rtdata->key, sizeof(char)*(x+1)); rtdata->key[x] = 0; rt->len++; return; } } } }
void __comps_mrtree_set(COMPS_MRTree * rt, char * key, size_t len, void * data) { static COMPS_HSListItem *it; COMPS_HSList *subnodes; COMPS_MRTreeData *rtd; static COMPS_MRTreeData *rtdata; size_t _len, offset=0; unsigned x, found = 0; void *ndata; char ended;//, tmpch; if (rt->subnodes == NULL) return; if (rt->data_constructor) ndata = rt->data_constructor(data); else ndata = data; subnodes = rt->subnodes; while (offset != len) { found = 0; for (it = subnodes->first; it != NULL; it=it->next) { if (((COMPS_MRTreeData*)it->data)->key[0] == key[offset]) { found = 1; break; } } if (!found) { // not found in subnodes; create new subnode rtd = comps_mrtree_data_create(rt, key+offset, ndata); comps_hslist_append(subnodes, rtd, 0); return; } else { rtdata = (COMPS_MRTreeData*)it->data; ended = 0; for (x=1; ;x++) { if (rtdata->key[x] == 0) ended += 1; if (x == len - offset) ended += 2; if (ended != 0) break; if (key[offset+x] != rtdata->key[x]) break; } if (ended == 3) { //keys equals; append new data comps_hslist_append(rtdata->data, ndata, 0); return; } else if (ended == 2) { //global key ends first; make global leaf comps_hslist_remove(subnodes, it); it->next = NULL; rtd = comps_mrtree_data_create(rt, key+offset, ndata); comps_hslist_append(subnodes, rtd, 0); ((COMPS_MRTreeData*)subnodes->last->data)->subnodes->last = it; ((COMPS_MRTreeData*)subnodes->last->data)->subnodes->first = it; _len = strlen(key + offset); memmove(rtdata->key,rtdata->key+_len, strlen(rtdata->key) - _len); rtdata->key[strlen(rtdata->key) - _len] = 0; rtdata->key = realloc(rtdata->key, sizeof(char)* (strlen(rtdata->key)+1)); return; } else if (ended == 1) { //local key ends first; go deeper subnodes = rtdata->subnodes; offset += x; } else { /* keys differ */ void *tmpdata = rtdata->data; COMPS_HSList *tmpnodes = rtdata->subnodes; int cmpret = strcmp(key+offset+x, rtdata->key+x); rtdata->subnodes = comps_hslist_create(); comps_hslist_init(rtdata->subnodes, NULL, NULL, &comps_mrtree_data_destroy_v); rtdata->data = NULL; if (cmpret > 0) { rtd = comps_mrtree_data_create(rt, rtdata->key+x, tmpdata); comps_hslist_destroy(&rtd->subnodes); rtd->subnodes = tmpnodes; comps_hslist_append(rtdata->subnodes, rtd, 0); rtd = comps_mrtree_data_create(rt, key+offset+x, ndata); comps_hslist_append(rtdata->subnodes, rtd, 0); } else { rtd = comps_mrtree_data_create(rt, key+offset+x, ndata); comps_hslist_append(rtdata->subnodes, rtd, 0); rtd = comps_mrtree_data_create(rt, rtdata->key+x, tmpdata); comps_hslist_destroy(&rtd->subnodes); rtd->subnodes = tmpnodes; comps_hslist_append(rtdata->subnodes, rtd, 0); } rtdata->key = realloc(rtdata->key, sizeof(char)*(x+1)); rtdata->key[x] = 0; return; } } } }