static int Equal(TreeMap *t1,TreeMap *t2) { struct Node *pt1,*pt2; if (t1 == t2) return 1; if (t1 == NULL || t2 == NULL) return 0; if (t1->count != t2->count) return 0; if (t1->Allocator != t2->Allocator) return 0; if (t1->compare != t2->compare) return 0; if (t1->ElementSize != t2->ElementSize) return 0; if (t1->Flags != t2->Flags) return 0; pt1 = bt_first(t1); pt2 = bt_first(t2); while (pt1 && pt2) { if (t1->compare(pt1->data,pt2->data,t1->aux)) break; pt1 = bt_next(t1,pt1); pt2 = bt_next(t2,pt2); } return 1; }
static int Save(TreeMap *src,FILE *stream, SaveFunction saveFn,void *arg) { struct Node *rvp; if (src == NULL) { iError.RaiseError("Save",CONTAINER_ERROR_BADARG); return CONTAINER_ERROR_BADARG; } if (stream == NULL) { src->RaiseError("Save",CONTAINER_ERROR_BADARG); return CONTAINER_ERROR_BADARG; } if (saveFn == NULL) { saveFn = DefaultSaveFunction; } if (fwrite(&TreeMapGuid,sizeof(guid),1,stream) <= 0) return EOF; if (arg == NULL) { arg = &src->ElementSize; } if (fwrite(src,1,sizeof(TreeMap),stream) <= 0) return EOF; rvp = bt_first(src); while (rvp) { char *p = rvp->data; if (saveFn(p,arg,stream) <= 0) return EOF; rvp = bt_next(src,rvp); } return 1; }
/* Returns the next data item in inorder within the tree being traversed with |trav|, or if there are no more data items returns |NULL|. */ static void *GetNext(Iterator *itrav) { struct TreeMapIterator *trav = (struct TreeMapIterator *)itrav; if (trav->timestamp != trav->bst_table->timestamp) return NULL; trav->bst_node = bt_next(trav->bst_table, trav->bst_node); if (trav->bst_node == NULL) return NULL; return trav->bst_node->data; }
/* Moves P around in BT to compensate for its key having changed. Returns a null pointer if successful. If P's new value is equal to that of some other node in BT, returns the other node after removing P from BT. This function is an optimization only if it is likely that P can actually retain its relative position in BT, e.g. its key has only been adjusted slightly. Otherwise, it is more efficient to simply remove P from BT, change its key, and re-insert P. It is not safe to update more than one node's key, then to call this function for each node. Instead, update a single node's key, call this function, update another node's key, and so on. Alternatively, remove all affected nodes from the tree, update their keys, then re-insert all of them. */ struct bt_node * bt_changed (struct bt *bt, struct bt_node *p) { struct bt_node *prev = bt_prev (bt, p); struct bt_node *next = bt_next (bt, p); if ((prev != NULL && bt->compare (prev, p, bt->aux) >= 0) || (next != NULL && bt->compare (p, next, bt->aux) >= 0)) { bt_delete (bt, p); return bt_insert (bt, p); } return NULL; }
int bt_seek(BTREE * bt, void *op, void *key) { u4 *node = &bt->root; int r = 0; while (*node) { r = bt->bt_compare(op, key, (void *) ((uchar *) NODE(*node) + sizeof(BT_NODE)), NULL); bt->cur = *node; if (r == 0) { if (!bt->unique) { while (!bt_prev(bt)) { r = bt->bt_compare(op, key, bt_key(bt), NULL); if (r) { bt_next(bt); break; } } } return 1; } if (r < 0) node = &(NODE(*node)->left); else node = &(NODE(*node)->right); } if (r > 0) bt_next(bt); return 0; }
static TreeMap *Copy(TreeMap *src) { TreeMap *result; struct Node *pSrc; if (src == NULL) { iError.RaiseError("Copy",CONTAINER_ERROR_BADARG); return NULL; } pSrc = bt_first(src); result = CreateWithAllocator(src->ElementSize,src->Allocator); while (pSrc) { iTreeMap.Add(result,pSrc->data,NULL); pSrc = bt_next(src,pSrc); } return result; }
int cdx_calcfiltlist(ClipMachine * ClipMachineMemory, RDD_DATA * rd, RDD_ORDER * ro, RDD_FILTER * fp, const char *__PROC__) { int i, er; BTREE *bt; void *key = malloc(sizeof(unsigned int) + ro->bufsize); ClipVar vv, *vp; if (fp->list) { bt = bt_create(0, fp->listlen, sizeof(unsigned int) + ro->bufsize, _cdx_compare); for (i = 0; i < fp->listlen; i++) { if ((er = rd->vtbl->rawgo(ClipMachineMemory, rd, fp->list[i], 0, __PROC__))) return er; if (ro->simpexpr) { if ((er = rd->vtbl->getvalue(ClipMachineMemory, rd, ro->simpfno, &vv, __PROC__))) return er; vp = &vv; } else { if ((er = rdd_calc(ClipMachineMemory, rd->area, &ro->block, &vv, 0))) return er; vp = _clip_vptr(&vv); } memcpy(key, &rd->recno, sizeof(unsigned int)); if ((er = cdx_formatkey(ClipMachineMemory, ro, vp, key + sizeof(unsigned int), __PROC__))) return er; _clip_destroy(ClipMachineMemory, &vv); bt_add(bt, ro, key); } free(fp->list); } else { #if 1 unsigned int bytes = ((fp->size + 1) >> 5) + 1; int i, b, bb, t, tt; fp->listlen = 0; for (i = 0; i < bytes; i++) { if (fp->rmap[i]) { for (b = (i << 2), bb = 0; bb < 4; b++, bb++) { if (((char *) fp->rmap)[b]) { for (t = (b << 3) + 1, tt = 0; tt < 8; t++, tt++) { if (_rm_getbit(fp->rmap, fp->size, t)) fp->listlen++; } } } } } if (fp->listlen > 100) { free(key); return 0; } #else fp->listlen = 0; for (i = 1; i <= fp->size; i++) if (_rm_getbit(fp->rmap, fp->size, i)) fp->listlen++; #endif bt = bt_create(0, fp->listlen, sizeof(unsigned int) + ro->bufsize, _cdx_compare); #if 1 for (i = 0; i < bytes; i++) { if (fp->rmap[i]) { for (b = (i << 2), bb = 0; bb < 4; b++, bb++) { if (((char *) fp->rmap)[b]) { for (t = (b << 3) + 1, tt = 0; tt < 8; t++, tt++) { if (_rm_getbit(fp->rmap, fp->size, t)) { if ((er = rd->vtbl->rawgo(ClipMachineMemory, rd, t, 0, __PROC__))) return er; if (ro->simpexpr) { if ((er = rd->vtbl->getvalue(ClipMachineMemory, rd, ro->simpfno, &vv, __PROC__))) return er; vp = &vv; } else { if ((er = rdd_calc(ClipMachineMemory, rd->area, &ro->block, &vv, 0))) return er; vp = _clip_vptr(&vv); } memcpy(key, &rd->recno, sizeof(unsigned int)); if ((er = cdx_formatkey(ClipMachineMemory, ro, vp, key + sizeof(unsigned int), __PROC__))) return er; _clip_destroy(ClipMachineMemory, &vv); bt_add(bt, ro, key); } } } } } } #else for (i = 1; i <= fp->size; i++) { if (_rm_getbit(fp->rmap, fp->size, i)) { if ((er = rd->vtbl->rawgo(ClipMachineMemory, rd, i, 0, __PROC__))) return er; if (ro->simpexpr) { if ((er = rd->vtbl->getvalue(ClipMachineMemory, rd, ro->simpfno, &vv, __PROC__))) return er; vp = &vv; } else { if ((er = rdd_calc(ClipMachineMemory, rd->area, &ro->block, &vv, 0))) return er; vp = _clip_vptr(&vv); } memcpy(key, &rd->recno, sizeof(unsigned int)); if ((er = cdx_formatkey(ClipMachineMemory, ro, vp, key + sizeof(unsigned int), __PROC__))) return er; _clip_destroy(ClipMachineMemory, &vv); bt_add(bt, ro, key); } } #endif } fp->list = malloc(sizeof(unsigned int) * (fp->listlen + 1)); if (!ro->descend) { bt_first(bt); if (bt_key(bt)) { i = 0; fp->list[i] = *(unsigned int *) bt_key(bt); while (!bt_next(bt)) { i++; fp->list[i] = *(unsigned int *) bt_key(bt); } } } else { bt_last(bt); if (bt_key(bt)) { i = 0; fp->list[i] = *(unsigned int *) bt_key(bt); while (!bt_prev(bt)) { i++; fp->list[i] = *(unsigned int *) bt_key(bt); } } } bt_destroy(bt); free(key); return 0; }