Tweet
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
typedef long eAdrType;
typedef long bAdrType;
#define CC_EQ 0
#define CC_GT 1
#define CC_LT -1
typedef int (*bCompType)(const void *key1, const void *key2);
int maxHeight;
int nNodesIns;
int nNodesDel;
int nKeysIns;
int nKeysDel;
int nDiskReads;
int nDiskWrites;
int bErrLineNo;
typedef enum {false, true} bool;
typedef enum {
bErrOk,
bErrKeyNotFound,
bErrDupKeys,
bErrSectorSize,
bErrFileNotOpen,
bErrFileExists,
bErrIO,
bErrMemory
} bErrType;
typedef void *bHandleType;
typedef struct {
char *iName;
int keySize;
bool dupKeys;
int sectorSize;
bCompType comp;
} bOpenType;
bErrType bOpen(bOpenType info, bHandleType *handle);
bErrType bClose(bHandleType handle);
bErrType bInsertKey(bHandleType handle, void *key, eAdrType rec);
bErrType bDeleteKey(bHandleType handle, void *key, eAdrType *rec);
bErrType bFindKey(bHandleType handle, void *key, eAdrType *rec);
bErrType bFindFirstKey(bHandleType handle, void *key, eAdrType *rec);
bErrType bFindLastKey(bHandleType handle, void *key, eAdrType *rec);
bErrType bFindNextKey(bHandleType handle, void *key, eAdrType *rec);
bErrType bFindPrevKey(bHandleType handle, void *key, eAdrType *rec);
#define bAdr(p) *(bAdrType *)(p)
#define eAdr(p) *(eAdrType *)(p)
#define childLT(k) bAdr((char *)k - sizeof(bAdrType))
#define key(k) (k)
#define rec(k) eAdr((char *)(k) + h->keySize)
#define childGE(k) bAdr((char *)(k) + h->keySize + sizeof(eAdrType))
#define leaf(b) b->p->leaf
#define ct(b) b->p->ct
#define next(b) b->p->next
#define prev(b) b->p->prev
#define fkey(b) &b->p->fkey
#define lkey(b) (fkey(b) + ks((ct(b) - 1)))
#define p(b) (char *)(b->p)
#define ks(ct) ((ct) * h->ks)
typedef char keyType;
typedef struct {
unsigned int leaf:1;
unsigned int ct:15;
bAdrType prev;
bAdrType next;
bAdrType childLT;
keyType fkey;
} nodeType;
typedef struct bufTypeTag {
struct bufTypeTag *next;
struct bufTypeTag *prev;
bAdrType adr;
nodeType *p;
bool valid;
bool modified;
} bufType;
typedef struct hNodeTag {
struct hNodeTag *prev;
struct hNodeTag *next;
FILE *fp;
int keySize;
bool dupKeys;
int sectorSize;
bCompType comp;
bufType root;
bufType bufList;
void *malloc1;
void *malloc2;
bufType gbuf;
bufType *curBuf;
keyType *curKey;
unsigned int maxCt;
int ks;
bAdrType nextFreeAdr;
} hNode;
static hNode hList;
static hNode *h;
#define error(rc) lineError(__LINE__, rc)
static bErrType lineError(int lineno, bErrType rc) {
if (rc == bErrIO || rc == bErrMemory)
if (!bErrLineNo)
bErrLineNo = lineno;
return rc;
}
static bAdrType allocAdr(void) {
bAdrType adr;
adr = h->nextFreeAdr;
h->nextFreeAdr += h->sectorSize;
return adr;
}
static bErrType flush(bufType *buf) {
int len;
len = h->sectorSize;
if (buf->adr == 0) len *= 3;
if (fseek(h->fp, buf->adr, SEEK_SET)) return error(bErrIO);
if (fwrite(buf->p, len, 1, h->fp) != 1) return error(bErrIO);
buf->modified = false;
nDiskWrites++;
return bErrOk;
}
static bErrType flushAll(void) {
bErrType rc;
bufType *buf;
if (h->root.modified)
if ((rc = flush(&h->root)) != 0) return rc;
buf = h->bufList.next;
while (buf != &h->bufList) {
if (buf->modified)
if ((rc = flush(buf)) != 0) return rc;
buf = buf->next;
}
}
static bErrType assignBuf(bAdrType adr, bufType **b) {
bufType *buf;
bErrType rc;
if (adr == 0) {
*b = &h->root;
return bErrOk;
}
buf = h->bufList.next;
while (buf->next != &h->bufList) {
if (buf->valid && buf->adr == adr) break;
buf = buf->next;
}
if (buf->valid) {
if (buf->adr != adr) {
if (buf->modified) {
if ((rc = flush(buf)) != 0) return rc;
}
buf->adr = adr;
buf->valid = false;
}
} else {
buf->adr = adr;
}
buf->next->prev = buf->prev;
buf->prev->next = buf->next;
buf->next = h->bufList.next;
buf->prev = &h->bufList;
buf->next->prev = buf;
buf->prev->next = buf;
*b = buf;
return bErrOk;
}
static bErrType writeDisk(bufType *buf) {
buf->valid = true;
buf->modified = true;
return bErrOk;
}
static bErrType readDisk(bAdrType adr, bufType **b) {
int len;
bufType *buf;
bErrType rc;
if ((rc = assignBuf(adr, &buf)) != 0) return rc;
if (!buf->valid) {
len = h->sectorSize;
if (adr == 0) len *= 3;
if (fseek(h->fp, adr, SEEK_SET)) return error(bErrIO);
if (fread(buf->p, len, 1, h->fp) != 1) return error(bErrIO);
buf->modified = false;
buf->valid = true;
nDiskReads++;
}
*b = buf;
return bErrOk;
}
typedef enum { MODE_FIRST, MODE_MATCH } modeEnum;
static int search(
bufType *buf,
void *key,
eAdrType rec,
keyType **mkey,
modeEnum mode) {
int cc;
int m;
int lb;
int ub;
bool foundDup;
foundDup = false;
lb = 0;
ub = ct(buf) - 1;
while (lb <= ub) {
m = (lb + ub) / 2;
*mkey = fkey(buf) + ks(m);
cc = h->comp(key, key(*mkey));
if (cc < 0)
ub = m - 1;
else if (cc > 0)
lb = m + 1;
else {
if (h->dupKeys) {
switch (mode) {
case MODE_FIRST:
ub = m - 1;
foundDup = true;
break;
case MODE_MATCH:
if (rec < rec(*mkey)) {
ub = m - 1;
cc = CC_LT;
} else if (rec > rec(*mkey)) {
lb = m + 1;
cc = CC_GT;
} else {
return CC_EQ;
}
break;
}
} else {
return cc;
}
}
}
if (ct(buf) == 0) {
*mkey = fkey(buf);
return CC_LT;
}
if (h->dupKeys && (mode == MODE_FIRST) && foundDup) {
*mkey += ks(1);
return CC_EQ;
}
return cc;
}
static bErrType scatterRoot(void) {
bufType *gbuf;
bufType *root;
root = &h->root;
gbuf = &h->gbuf;
memcpy(fkey(root), fkey(gbuf), ks(ct(gbuf)));
childLT(fkey(root)) = childLT(fkey(gbuf));
ct(root) = ct(gbuf);
leaf(root) = leaf(gbuf);
return bErrOk;
}
static bErrType scatter(bufType *pbuf, keyType *pkey, int is, bufType **tmp) {
bufType *gbuf;
keyType *gkey;
bErrType rc;
int iu;
int k0Min;
int knMin;
int k0Max;
int knMax;
int sw;
int len;
int base;
int extra;
int ct;
int i;
gbuf = &h->gbuf;
gkey = fkey(gbuf);
ct = ct(gbuf);
iu = is;
if (leaf(gbuf)) {
k0Max= h->maxCt - 1;
knMax= h->maxCt - 1;
k0Min= (h->maxCt / 2) + 1;
knMin= (h->maxCt / 2) + 1;
} else {
k0Max = h->maxCt - 1;
knMax = h->maxCt;
k0Min = (h->maxCt / 2) + 1;
knMin = ((h->maxCt+1) / 2) + 1;
}
while(1) {
if (iu == 0 || ct > (k0Max + (iu-1)*knMax)) {
if ((rc = assignBuf(allocAdr(), &tmp[iu])) != 0)
return rc;
if (leaf(gbuf)) {
if (iu == 0) {
prev(tmp[0]) = 0;
next(tmp[0]) = 0;
} else {
prev(tmp[iu]) = tmp[iu-1]->adr;
next(tmp[iu]) = next(tmp[iu-1]);
next(tmp[iu-1]) = tmp[iu]->adr;
}
}
iu++;
nNodesIns++;
} else if (iu > 1 && ct < (k0Min + (iu-1)*knMin)) {
iu--;
if (leaf(gbuf) && tmp[iu-1]->adr) {
next(tmp[iu-1]) = next(tmp[iu]);
}
next(tmp[iu-1]) = next(tmp[iu]);
nNodesDel++;
} else {
break;
}
}
base = ct / iu;
extra = ct % iu;
for (i = 0; i < iu; i++) {
int n;
n = base;
if (i && extra) {
n++;
extra--;
}
ct(tmp[i]) = n;
}
if (iu != is) {
if (leaf(gbuf) && next(tmp[iu-1])) {
bufType *buf;
if ((rc = readDisk(next(tmp[iu-1]), &buf)) != 0) return rc;
prev(buf) = tmp[iu-1]->adr;
if ((rc = writeDisk(buf)) != 0) return rc;
}
sw = ks(iu - is);
if (sw < 0) {
len = ks(ct(pbuf)) - (pkey - fkey(pbuf)) + sw;
memmove(pkey, pkey - sw, len);
} else {
len = ks(ct(pbuf)) - (pkey - fkey(pbuf));
memmove(pkey + sw, pkey, len);
}
if (ct(pbuf))
ct(pbuf) += iu - is;
else
ct(pbuf) += iu - is - 1;
}
for (i = 0; i < iu; i++) {
if (leaf(gbuf)) {
childLT(fkey(tmp[i])) = 0;
if (i == 0) {
childLT(pkey) = tmp[i]->adr;
} else {
memcpy(pkey, gkey, ks(1));
childGE(pkey) = tmp[i]->adr;
pkey += ks(1);
}
} else {
if (i == 0) {
childLT(fkey(tmp[i])) = childLT(gkey);
childLT(pkey) = tmp[i]->adr;
} else {
childLT(fkey(tmp[i])) = childGE(gkey);
memcpy(pkey, gkey, ks(1));
childGE(pkey) = tmp[i]->adr;
gkey += ks(1);
pkey += ks(1);
ct(tmp[i])--;
}
}
memcpy(fkey(tmp[i]), gkey, ks(ct(tmp[i])));
leaf(tmp[i]) = leaf(gbuf);
gkey += ks(ct(tmp[i]));
}
leaf(pbuf) = false;
if ((rc = writeDisk(pbuf)) != 0) return rc;
for (i = 0; i < iu; i++)
if ((rc = writeDisk(tmp[i])) != 0) return rc;
return bErrOk;
}
static bErrType gatherRoot(void) {
bufType *gbuf;
bufType *root;
root = &h->root;
gbuf = &h->gbuf;
memcpy(p(gbuf), root->p, 3 * h->sectorSize);
leaf(gbuf) = leaf(root);
ct(root) = 0;
return bErrOk;
}
static bErrType gather(bufType *pbuf, keyType **pkey, bufType **tmp) {
bErrType rc;
bufType *gbuf;
keyType *gkey;
if (*pkey == lkey(pbuf))
*pkey -= ks(1);
if ((rc = readDisk(childLT(*pkey), &tmp[0])) != 0) return rc;
if ((rc = readDisk(childGE(*pkey), &tmp[1])) != 0) return rc;
if ((rc = readDisk(childGE(*pkey + ks(1)), &tmp[2])) != 0) return rc;
gbuf = &h->gbuf;
gkey = fkey(gbuf);
childLT(gkey) = childLT(fkey(tmp[0]));
memcpy(gkey, fkey(tmp[0]), ks(ct(tmp[0])));
gkey += ks(ct(tmp[0]));
ct(gbuf) = ct(tmp[0]);
if (!leaf(tmp[1])) {
memcpy(gkey, *pkey, ks(1));
childGE(gkey) = childLT(fkey(tmp[1]));
ct(gbuf)++;
gkey += ks(1);
}
memcpy(gkey, fkey(tmp[1]), ks(ct(tmp[1])));
gkey += ks(ct(tmp[1]));
ct(gbuf) += ct(tmp[1]);
if (!leaf(tmp[2])) {
memcpy(gkey, *pkey+ks(1), ks(1));
childGE(gkey) = childLT(fkey(tmp[2]));
ct(gbuf)++;
gkey += ks(1);
}
memcpy(gkey, fkey(tmp[2]), ks(ct(tmp[2])));
ct(gbuf) += ct(tmp[2]);
leaf(gbuf) = leaf(tmp[0]);
return bErrOk;
}
bErrType bOpen(bOpenType info, bHandleType *handle) {
bErrType rc;
int bufCt;
bufType *buf;
int maxCt;
bufType *root;
int i;
nodeType *p;
if ((info.sectorSize < sizeof(hNode)) || (info.sectorSize % 4))
return bErrSectorSize;
maxCt = info.sectorSize - (sizeof(nodeType) - sizeof(keyType));
maxCt /= sizeof(bAdrType) + info.keySize + sizeof(eAdrType);
if (maxCt < 6) return bErrSectorSize;
if ((h = malloc(sizeof(hNode))) == NULL) return error(bErrMemory);
memset(h, 0, sizeof(hNode));
h->keySize = info.keySize;
h->dupKeys = info.dupKeys;
h->sectorSize = info.sectorSize;
h->comp = info.comp;
h->ks = sizeof(bAdrType) + h->keySize + sizeof(eAdrType);
h->maxCt = maxCt;
bufCt = 7;
if ((h->malloc1 = malloc(bufCt * sizeof(bufType))) == NULL)
return error(bErrMemory);
buf = h->malloc1;
if ((h->malloc2 = malloc((bufCt+6) * h->sectorSize + 2 * h->ks)) == NULL)
return error(bErrMemory);
p = h->malloc2;
h->bufList.next = buf;
h->bufList.prev = buf + (bufCt - 1);
for (i = 0; i < bufCt; i++) {
buf->next = buf + 1;
buf->prev = buf - 1;
buf->modified = false;
buf->valid = false;
buf->p = p;
p = (nodeType *)((char *)p + h->sectorSize);
buf++;
}
h->bufList.next->prev = &h->bufList;
h->bufList.prev->next = &h->bufList;
root = &h->root;
root->p = p;
p = (nodeType *)((char *)p + 3*h->sectorSize);
h->gbuf.p = p;
h->curBuf = NULL;
h->curKey = NULL;
if ((h->fp = fopen(info.iName, "r+b")) != NULL) {
if ((rc = readDisk(0, &root)) != 0) return rc;
if (fseek(h->fp, 0, SEEK_END)) return error(bErrIO);
if ((h->nextFreeAdr = ftell(h->fp)) == -1) return error(bErrIO);
} else if ((h->fp = fopen(info.iName, "w+b")) != NULL) {
memset(root->p, 0, 3*h->sectorSize);
leaf(root) = 1;
h->nextFreeAdr = 3 * h->sectorSize;
} else {
/* something's wrong */
free(h);
return bErrFileNotOpen;
}
if (hList.next) {
h->prev = hList.next;
h->next = &hList;
h->prev->next = h;
h->next->prev = h;
} else {
/* first item in hList */
h->prev = h->next = &hList;
hList.next = hList.prev = h;
}
*handle = h;
return bErrOk;
}
bErrType bClose(bHandleType handle) {
h = handle;
if (h == NULL) return bErrOk;
if (h->next) {
h->next->prev = h->prev;
h->prev->next = h->next;
}
if (h->fp) {
flushAll();
fclose(h->fp);
}
if (h->malloc2) free(h->malloc2);
if (h->malloc1) free(h->malloc1);
free(h);
return bErrOk;
}
bErrType bFindKey(bHandleType handle, void *key, eAdrType *rec) {
keyType *mkey;
bufType *buf;
bErrType rc;
h = handle;
buf = &h->root;
while (1) {
if (leaf(buf)) {
if (search(buf, key, 0, &mkey, MODE_FIRST) == 0) {
*rec = rec(mkey);
h->curBuf = buf; h->curKey = mkey;
return bErrOk;
} else {
return bErrKeyNotFound;
}
} else {
if (search(buf, key, 0, &mkey, MODE_FIRST) < 0) {
if ((rc = readDisk(childLT(mkey), &buf)) != 0) return rc;
} else {
if ((rc = readDisk(childGE(mkey), &buf)) != 0) return rc;
}
}
}
}
bErrType bInsertKey(bHandleType handle, void *key, eAdrType rec) {
int rc;
keyType *mkey;
int len;
int cc;
bufType *buf, *root;
bufType *tmp[4];
unsigned int keyOff;
bool lastGEvalid;
bool lastLTvalid;
bAdrType lastGE;
unsigned int lastGEkey;
int height;
h = handle;
root = &h->root;
lastGEvalid = false;
lastLTvalid = false;
if (ct(root) == 3 * h->maxCt) {
if ((rc = gatherRoot()) != 0) return rc;
if ((rc = scatter(root, fkey(root), 0, tmp)) != 0) return rc;
}
buf = root;
height = 0;
while(1) {
if (leaf(buf)) {
if (height > maxHeight) maxHeight = height;
switch(search(buf, key, rec, &mkey, MODE_MATCH)) {
case CC_LT:
if (!h->dupKeys && h->comp(key, mkey) == CC_EQ)
return bErrDupKeys;
break;
case CC_EQ:
return bErrDupKeys;
break;
case CC_GT:
if (!h->dupKeys && h->comp(key, mkey) == CC_EQ)
return bErrDupKeys;
mkey += ks(1);
break;
}
keyOff = mkey - fkey(buf);
len = ks(ct(buf)) - keyOff;
if (len) memmove(mkey + ks(1), mkey, len);
memcpy(key(mkey), key, h->keySize);
rec(mkey) = rec;
childGE(mkey) = 0;
ct(buf)++;
if ((rc = writeDisk(buf)) != 0) return rc;
if (!keyOff && lastLTvalid) {
bufType *tbuf;
keyType *tkey;
if ((rc = readDisk(lastGE, &tbuf)) != 0) return rc;
tkey = fkey(tbuf) + lastGEkey;
memcpy(key(tkey), key, h->keySize);
rec(tkey) = rec;
if ((rc = writeDisk(tbuf)) != 0) return rc;
}
nKeysIns++;
break;
} else {
bufType *cbuf;
height++;
if ((cc = search(buf, key, rec, &mkey, MODE_MATCH)) < 0) {
if ((rc = readDisk(childLT(mkey), &cbuf)) != 0) return rc;
} else {
if ((rc = readDisk(childGE(mkey), &cbuf)) != 0) return rc;
}
if (ct(cbuf) == h->maxCt) {
if ((rc = gather(buf, &mkey, tmp)) != 0) return rc;
if ((rc = scatter(buf, mkey, 3, tmp)) != 0) return rc;
if ((cc = search(buf, key, rec, &mkey, MODE_MATCH)) < 0) {
if ((rc = readDisk(childLT(mkey), &cbuf)) != 0) return rc;
} else {
if ((rc = readDisk(childGE(mkey), &cbuf)) != 0) return rc;
}
}
if (cc >= 0 || mkey != fkey(buf)) {
lastGEvalid = true;
lastLTvalid = false;
lastGE = buf->adr;
lastGEkey = mkey - fkey(buf);
if (cc < 0) lastGEkey -= ks(1);
} else {
if (lastGEvalid) lastLTvalid = true;
}
buf = cbuf;
}
}
return bErrOk;
}
bErrType bDeleteKey(bHandleType handle, void *key, eAdrType *rec) {
int rc;
keyType *mkey;
int len;
int cc;
bufType *buf;
bufType *tmp[4];
unsigned int keyOff;
bool lastGEvalid;
bool lastLTvalid;
bAdrType lastGE;
unsigned int lastGEkey;
bufType *root;
bufType *gbuf;
h = handle;
root = &h->root;
gbuf = &h->gbuf;
lastGEvalid = false;
lastLTvalid = false;
buf = root;
while(1) {
if (leaf(buf)) {
if (search(buf, key, *rec, &mkey, MODE_MATCH) == 0)
*rec = rec(mkey);
else
return bErrKeyNotFound;
keyOff = mkey - fkey(buf);
len = ks(ct(buf)-1) - keyOff;
if (len) memmove(mkey, mkey + ks(1), len);
ct(buf)--;
if ((rc = writeDisk(buf)) != 0) return rc;
if (!keyOff && lastLTvalid) {
bufType *tbuf;
keyType *tkey;
if ((rc = readDisk(lastGE, &tbuf)) != 0) return rc;
tkey = fkey(tbuf) + lastGEkey;
memcpy(key(tkey), mkey, h->keySize);
rec(tkey) = rec(mkey);
if ((rc = writeDisk(tbuf)) != 0) return rc;
}
nKeysDel++;
break;
} else {
bufType *cbuf;
if ((cc = search(buf, key, *rec, &mkey, MODE_MATCH)) < 0) {
if ((rc = readDisk(childLT(mkey), &cbuf)) != 0) return rc;
} else {
if ((rc = readDisk(childGE(mkey), &cbuf)) != 0) return rc;
}
if (ct(cbuf) == h->maxCt/2) {
if ((rc = gather(buf, &mkey, tmp)) != 0) return rc;
if (buf == root
&& ct(root) == 2
&& ct(gbuf) < (3*(3*h->maxCt))/4) {
scatterRoot();
nNodesDel += 3;
continue;
}
if ((rc = scatter(buf, mkey, 3, tmp)) != 0) return rc;
if ((cc = search(buf, key, *rec, &mkey, MODE_MATCH)) < 0) {
if ((rc = readDisk(childLT(mkey), &cbuf)) != 0) return rc;
} else {
if ((rc = readDisk(childGE(mkey), &cbuf)) != 0) return rc;
}
}
if (cc >= 0 || mkey != fkey(buf)) {
lastGEvalid = true;
lastLTvalid = false;
lastGE = buf->adr;
lastGEkey = mkey - fkey(buf);
if (cc < 0) lastGEkey -= ks(1);
} else {
if (lastGEvalid) lastLTvalid = true;
}
buf = cbuf;
}
}
return bErrOk;
}
bErrType bFindFirstKey(bHandleType handle, void *key, eAdrType *rec) {
bErrType rc;
bufType *buf;
h = handle;
buf = &h->root;
while (!leaf(buf)) {
if ((rc = readDisk(childLT(fkey(buf)), &buf)) != 0) return rc;
}
if (ct(buf) == 0) return bErrKeyNotFound;
memcpy(key, key(fkey(buf)), h->keySize);
*rec = rec(fkey(buf));
h->curBuf = buf; h->curKey = fkey(buf);
return bErrOk;
}
bErrType bFindLastKey(bHandleType handle, void *key, eAdrType *rec) {
bErrType rc;
bufType *buf;
h = handle;
buf = &h->root;
while (!leaf(buf)) {
if ((rc = readDisk(childGE(lkey(buf)), &buf)) != 0) return rc;
}
if (ct(buf) == 0) return bErrKeyNotFound;
memcpy(key, key(lkey(buf)), h->keySize);
*rec = rec(lkey(buf));
h->curBuf = buf; h->curKey = lkey(buf);
return bErrOk;
}
bErrType bFindNextKey(bHandleType handle, void *key, eAdrType *rec) {
bErrType rc;
keyType *nkey;
bufType *buf;
h = handle;
if ((buf = h->curBuf) == NULL) return bErrKeyNotFound;
if (h->curKey == lkey(buf)) {
if (next(buf)) {
if ((rc = readDisk(next(buf), &buf)) != 0) return rc;
nkey = fkey(buf);
} else {
return bErrKeyNotFound;
}
} else {
nkey = h->curKey + ks(1);
}
memcpy(key, key(nkey), h->keySize);
*rec = rec(nkey);
h->curBuf = buf; h->curKey = nkey;
return bErrOk;
}
bErrType bFindPrevKey(bHandleType handle, void *key, eAdrType *rec) {
bErrType rc;
keyType *pkey;
keyType *fkey;
bufType *buf;
h = handle;
if ((buf = h->curBuf) == NULL) return bErrKeyNotFound;
fkey = fkey(buf);
if (h->curKey == fkey) {
if (prev(buf)) {
if ((rc = readDisk(prev(buf), &buf)) != 0) return rc;
pkey = fkey(buf) + ks((ct(buf) - 1));
} else {
return bErrKeyNotFound;
}
} else {
pkey = h->curKey - ks(1);
}
memcpy(key, key(pkey), h->keySize);
*rec = rec(pkey);
h->curBuf = buf; h->curKey = pkey;
return bErrOk;
}
int comp(const void *key1, const void *key2) {
unsigned int const *p1;
unsigned int const *p2;
p1 = key1; p2 = key2;
return (*p1 == *p2) ? CC_EQ : (*p1 > *p2 ) ? CC_GT : CC_LT;
}
int main(void) {
bOpenType info;
bHandleType handle;
bErrType rc;
unsigned int key;
remove("t1.dat");
info.iName = "t1.dat";
info.keySize = sizeof(int);
info.dupKeys = false;
info.sectorSize = 256;
info.comp = comp;
if ((rc = bOpen(info, &handle)) != bErrOk) {
printf("line %d: rc = %d\n", __LINE__, rc);
exit(0);
}
key = 0x11;
if ((rc = bInsertKey(handle, &key, 0x300)) != bErrOk) {
printf("line %d: rc = %d\n", __LINE__, rc);
exit(0);
}
bClose(handle);
printf("statistics:\n");
printf(" maximum height: %4d\n", maxHeight);
printf(" nodes inserted: %4d\n", nNodesIns);
printf(" nodes deleted: %4d\n", nNodesDel);
printf(" keys inserted: %4d\n", nKeysIns);
printf(" keys deleted: %4d\n", nKeysDel);
printf(" disk reads: %4d\n", nDiskReads);
printf(" disk writes: %4d\n", nDiskWrites);
return 0;
}
B-Tree Programming in C
Posted by
LAHAUL SETH
~
B-Tree Programming in C
2012-02-19T08:18:00+05:30
LAHAUL SETH
Tree
|
Comments
B-Tree Programming in C
2012-02-19T08:18:00+05:30
LAHAUL SETH
Tree
|