QSE_INLINE void qse_rbt_freepair (rbt_t* rbt, pair_t* pair) { if (rbt->style->freeer[QSE_RBT_KEY] != QSE_NULL) rbt->style->freeer[QSE_RBT_KEY] (rbt, KPTR(pair), KLEN(pair)); if (rbt->style->freeer[QSE_RBT_VAL] != QSE_NULL) rbt->style->freeer[QSE_RBT_VAL] (rbt, VPTR(pair), VLEN(pair)); QSE_MMGR_FREE (rbt->mmgr, pair); }
QSE_INLINE pair_t* qse_rbt_allocpair ( rbt_t* rbt, void* kptr, size_t klen, void* vptr, size_t vlen) { pair_t* n; copier_t kcop = rbt->style->copier[QSE_RBT_KEY]; copier_t vcop = rbt->style->copier[QSE_RBT_VAL]; size_t as = SIZEOF(pair_t); if (kcop == QSE_RBT_COPIER_INLINE) as += KTOB(rbt,klen); if (vcop == QSE_RBT_COPIER_INLINE) as += VTOB(rbt,vlen); n = (pair_t*) QSE_MMGR_ALLOC (rbt->mmgr, as); if (n == QSE_NULL) return QSE_NULL; n->color = QSE_RBT_RED; n->parent = QSE_NULL; n->child[LEFT] = &rbt->xnil; n->child[RIGHT] = &rbt->xnil; KLEN(n) = klen; if (kcop == QSE_RBT_COPIER_SIMPLE) { KPTR(n) = kptr; } else if (kcop == QSE_RBT_COPIER_INLINE) { KPTR(n) = n + 1; if (kptr) QSE_MEMCPY (KPTR(n), kptr, KTOB(rbt,klen)); } else { KPTR(n) = kcop (rbt, kptr, klen); if (KPTR(n) == QSE_NULL) { QSE_MMGR_FREE (rbt->mmgr, n); return QSE_NULL; } } VLEN(n) = vlen; if (vcop == QSE_RBT_COPIER_SIMPLE) { VPTR(n) = vptr; } else if (vcop == QSE_RBT_COPIER_INLINE) { VPTR(n) = n + 1; if (kcop == QSE_RBT_COPIER_INLINE) VPTR(n) = (byte_t*)VPTR(n) + KTOB(rbt,klen); if (vptr) QSE_MEMCPY (VPTR(n), vptr, VTOB(rbt,vlen)); } else { VPTR(n) = vcop (rbt, vptr, vlen); if (VPTR(n) != QSE_NULL) { if (rbt->style->freeer[QSE_RBT_KEY] != QSE_NULL) rbt->style->freeer[QSE_RBT_KEY] (rbt, KPTR(n), KLEN(n)); QSE_MMGR_FREE (rbt->mmgr, n); return QSE_NULL; } } return n; }
static pair_t* change_pair_val ( rbt_t* rbt, pair_t* pair, void* vptr, size_t vlen) { if (VPTR(pair) == vptr && VLEN(pair) == vlen) { /* if the old value and the new value are the same, * it just calls the handler for this condition. * No value replacement occurs. */ if (rbt->style->keeper != QSE_NULL) { rbt->style->keeper (rbt, vptr, vlen); } } else { copier_t vcop = rbt->style->copier[QSE_RBT_VAL]; void* ovptr = VPTR(pair); size_t ovlen = VLEN(pair); /* place the new value according to the copier */ if (vcop == QSE_RBT_COPIER_SIMPLE) { VPTR(pair) = vptr; VLEN(pair) = vlen; } else if (vcop == QSE_RBT_COPIER_INLINE) { if (ovlen == vlen) { if (vptr) QSE_MEMCPY (VPTR(pair), vptr, VTOB(rbt,vlen)); } else { /* need to reconstruct the pair */ pair_t* p = qse_rbt_allocpair (rbt, KPTR(pair), KLEN(pair), vptr, vlen); if (p == QSE_NULL) return QSE_NULL; p->color = pair->color; p->left = pair->left; p->right = pair->right; p->parent = pair->parent; if (pair->parent) { if (pair->parent->left == pair) { pair->parent->left = p; } else { QSE_ASSERT (pair->parent->right == pair); pair->parent->right = p; } } if (!IS_NIL(rbt,pair->left)) pair->left->parent = p; if (!IS_NIL(rbt,pair->right)) pair->right->parent = p; if (pair == rbt->root) rbt->root = p; qse_rbt_freepair (rbt, pair); return p; } } else { void* nvptr = vcop (rbt, vptr, vlen); if (nvptr == QSE_NULL) return QSE_NULL; VPTR(pair) = nvptr; VLEN(pair) = vlen; } /* free up the old value */ if (rbt->style->freeer[QSE_RBT_VAL] != QSE_NULL) { rbt->style->freeer[QSE_RBT_VAL] (rbt, ovptr, ovlen); } } return pair; }
int main() { int res = 0; int i; int x; int *xp; struct s * sp; PTR(B)[0] = 1; PTR(B)[1] = 2; PTR(B)[2] = 3; PTR(B)[3] = 4; SPTR(C)->f1 = 5; SPTR(D)->f2 = 6; #ifdef DEBUG printf("Address of a: %p\n",&a); printf("Address of b: %p\n",&b[0]); printf("Address of c: %p\n",&s.c); printf("Address of d: %p\n",&s.d); #endif /* store (non-volatile) to absolute address */ *PTR(A) = 17; /* load (non-volatile) from absolute address */ x = *PTR(A); res += EXPECT(17, x); /* store (volatile) to absolute address */ *VPTR(A) = 23; /* load (non-volatile) from absolute address */ x = *PTR(A); res += EXPECT(23, x); /* pointer arithmetic */ xp = PTR(B); for(i = 0; i < 3; i++) { if(*(PTR(B)+i) == 3) xp=PTR(B)+i; } x = *xp; res += EXPECT(3,x); /* Structs, larger base offset */ res += EXPECT(11, SPTR(C)->f1 + SPTR(D)->f2); /* Moving around in a larger memory area */ x = 0; sp = SPTR(C); i = 0; while(sp <= SPTR(D)) { #ifdef DEBUG printf("Writing at %p\n",sp); #endif sp->f1 = 0xafe; sp += STEP; if(i++ > 32) break; } i = 0; while(sp >= SPTR(C) + STEP) { #ifdef DEBUG printf("Reading at %p\n",sp); #endif sp -= STEP; x += sp->f1; if(i++ > 32) break; } dbg = i; res += EXPECT(5*0xafe, x); return res; /* expecting: 0 */ }