mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
134 lines
2.4 KiB
C
134 lines
2.4 KiB
C
// vim:syntax=lpc
|
|
#include <net.h>
|
|
|
|
// this isn't actually faster than expanding arrays. in fact, it's way slower.
|
|
// do not use until i find a search tree which makes this faster than array
|
|
// concatenation!
|
|
|
|
#ifndef BASE
|
|
# define BASE 8
|
|
#endif
|
|
|
|
#define I_TO 0
|
|
#define I_SUB 1
|
|
#define I_ISVALUE 2
|
|
#define I_NEXT 3
|
|
|
|
#if BASE == 2
|
|
# define BP(x) ((x) ? (2<<((x)-1)) : 1)
|
|
#elif BASE == 8
|
|
# define BP(x) ((x) ? (8<<(3*((x)-1))) : 1)
|
|
#else
|
|
# define NEED_TP
|
|
# define BP(x) tp(x)
|
|
#endif
|
|
|
|
private int _length, _max, _levels, _height;
|
|
private mixed *structure;
|
|
|
|
int length() { return _length; }
|
|
|
|
#ifdef NEED_TP
|
|
private int tp(int p) {
|
|
int res = BASE;
|
|
|
|
//PT(("}} %O\n", p))
|
|
|
|
unless (p) {
|
|
return 1;
|
|
}
|
|
|
|
while (--p) {
|
|
res *= BASE;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
#endif
|
|
|
|
void vAdd(mixed item) {
|
|
mixed *cur;
|
|
int level;
|
|
|
|
//PT(("adding %O, length %O, max %O\n", item, _length, _max))
|
|
unless (_length) {
|
|
_max = BASE;
|
|
_length++;
|
|
structure = ({ 0, item, 1, 0 });
|
|
return;
|
|
}
|
|
|
|
if (_length == _max) {
|
|
int tmax = _max;
|
|
|
|
_max *= BASE;
|
|
_height++;
|
|
|
|
structure = ({ tmax-1, structure, 0, 0 });
|
|
}
|
|
|
|
cur = structure;
|
|
|
|
for (;;) {
|
|
//PT(("%O, %O\n", cur[I_TO], _length))
|
|
if (cur[I_TO] < _length) {
|
|
unless (cur[I_NEXT]) {
|
|
int t;
|
|
|
|
//cur = cur[I_NEXT] = ({ (t = cur[I_TO]) + to_int(pow(10, _height-level)), 0, 0, 0 });
|
|
cur = cur[I_NEXT] = ({ (t = cur[I_TO]) + BP(_height-level), 0, 0, 0 });
|
|
|
|
//PT((">> %O; %O, %O\n", _height, level, cur))
|
|
while (_height-level++) {
|
|
//cur = cur[I_SUB] = ({ t + to_int(pow(10, _height-level)), 0, 0, 0 });
|
|
cur = cur[I_SUB] = ({ t + BP(_height-level), 0, 0, 0 });
|
|
}
|
|
|
|
cur[I_SUB] = item;
|
|
cur[I_ISVALUE] = 1;
|
|
|
|
_length++;
|
|
return;
|
|
}
|
|
cur = cur[I_NEXT];
|
|
} else if (cur[I_ISVALUE]) {
|
|
raise_error("DUH?\n");
|
|
cur[I_SUB] = item;
|
|
_length++;
|
|
return;
|
|
} else {
|
|
cur = cur[I_SUB];
|
|
level++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void debug() {
|
|
PT((">> %O\n", structure))
|
|
PT((">> %d, %d, %d, %d\n", BP(0), BP(1), BP(2), BP(3)))
|
|
}
|
|
|
|
vGet(int index) {
|
|
mixed *cur = structure;
|
|
int steps;
|
|
|
|
if (index >= _length) {
|
|
raise_error("index out of bounds\n");
|
|
}
|
|
|
|
for (;;) {
|
|
if (cur[I_TO] < index) {
|
|
unless (pointerp(cur[I_NEXT])) {
|
|
PT((":: %O\n", cur))
|
|
}
|
|
cur = cur[I_NEXT];
|
|
steps++;
|
|
} else if (cur[I_ISVALUE]) {
|
|
PT(("did %d steps\n", steps))
|
|
return cur[I_SUB];
|
|
} else {
|
|
cur = cur[I_SUB];
|
|
steps++;
|
|
}
|
|
}
|
|
}
|