|
Packit |
e4b6da |
#include "mtable.h"
|
|
Packit |
e4b6da |
#include <stdlib.h>
|
|
Packit |
e4b6da |
#include <string.h>
|
|
Packit |
e4b6da |
#include <stdio.h>
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
#define mtable_left_index(k, e) ((~((1<<(e))-1) & (k))>>(e))
|
|
Packit |
e4b6da |
#define mtable_right_index(k, e) (((1<<(e))-1) & (k))
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
static void *
|
|
Packit |
e4b6da |
mallocc(size_t size)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
void *p = malloc(size);
|
|
Packit |
e4b6da |
if(p == NULL) {
|
|
Packit |
e4b6da |
fprintf(stderr, "out of memory\n");
|
|
Packit |
e4b6da |
abort();
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
return p;
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
static mtable_t
|
|
Packit |
e4b6da |
mtable_new2(int *exponents)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
void **p = mallocc(sizeof(void *) * (1 + (1<
|
|
Packit |
e4b6da |
p[0] = exponents;
|
|
Packit |
e4b6da |
memset(p+1, 0, sizeof(void *) * (1<
|
|
Packit |
e4b6da |
return (mtable_t) p;
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
mtable_t
|
|
Packit |
e4b6da |
mtable_new(int *exponents)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
int n;
|
|
Packit |
e4b6da |
int *exponents_copy;
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
for(n=0; exponents[n++] != 0; );
|
|
Packit |
e4b6da |
exponents_copy = mallocc(sizeof(int) * n);
|
|
Packit |
e4b6da |
while(n > 0) {
|
|
Packit |
e4b6da |
n--;
|
|
Packit |
e4b6da |
exponents_copy[n] = exponents[n];
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
return mtable_new2(exponents_copy);
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
static void
|
|
Packit |
e4b6da |
mtable_delete2(mtable_t mtab, int e_sum, int start)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
if(mtab->exponents[1] != 0) {
|
|
Packit |
e4b6da |
int k;
|
|
Packit |
e4b6da |
int e = mtab->exponents[0];
|
|
Packit |
e4b6da |
void **p = &(mtab->slots[0]);
|
|
Packit |
e4b6da |
for(k=0; k<(1<
|
|
Packit |
e4b6da |
if(*p != NULL)
|
|
Packit |
e4b6da |
mtable_delete2(*p, e_sum-e, start+(k<<(e_sum-e)));
|
|
Packit |
e4b6da |
p++;
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
free(mtab);
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
void
|
|
Packit |
e4b6da |
mtable_delete(mtable_t mtab)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
int i, e_sum=0, *exponents;
|
|
Packit |
e4b6da |
for(i=0; mtab->exponents[i] != 0; i++)
|
|
Packit |
e4b6da |
e_sum += mtab->exponents[i];
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
exponents = mtab->exponents;
|
|
Packit |
e4b6da |
mtable_delete2(mtab, e_sum, 0);
|
|
Packit |
e4b6da |
free(exponents);
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
#if 0
|
|
Packit |
e4b6da |
static void
|
|
Packit |
e4b6da |
mtable_change_exponents(mtable_t mtab, int *exponents)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
if(mtab->exponents[1] != 0) {
|
|
Packit |
e4b6da |
int k;
|
|
Packit |
e4b6da |
int e = mtab->exponents[0];
|
|
Packit |
e4b6da |
void **p = &(mtab->slots[0]);
|
|
Packit |
e4b6da |
for(k=0; k<(1<
|
|
Packit |
e4b6da |
if(*p != NULL)
|
|
Packit |
e4b6da |
mtable_change_exponents(*p, exponents+1);
|
|
Packit |
e4b6da |
p++;
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
mtab->exponents = exponents;
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
mtable_t
|
|
Packit |
e4b6da |
mtable_extend(mtable_t mtab, int *exponents)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
struct mtable *p;
|
|
Packit |
e4b6da |
int *all_exponents, *old_exponents;
|
|
Packit |
e4b6da |
int n = 0;
|
|
Packit |
e4b6da |
int i = 0;
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
for(n=0; exponents[n++] != 0; );
|
|
Packit |
e4b6da |
for(i=0; mtab->exponents[i++] != 0; );
|
|
Packit |
e4b6da |
all_exponents = mallocc(sizeof(int) * (n-1+i));
|
|
Packit |
e4b6da |
for(i=0; exponents[i] != 0; i++)
|
|
Packit |
e4b6da |
all_exponents[i] = exponents[i];
|
|
Packit |
e4b6da |
for(i=0; mtab->exponents[i] != 0; i++)
|
|
Packit |
e4b6da |
all_exponents[n-1+i] = mtab->exponents[i];
|
|
Packit |
e4b6da |
all_exponents[n-1+i] = 0;
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
p = mtable_new2(exponents);
|
|
Packit |
e4b6da |
mtable_set(p, 0, mtab);
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
old_exponents = mtab->exponents;
|
|
Packit |
e4b6da |
mtable_change_exponents(p, all_exponents);
|
|
Packit |
e4b6da |
mtable_change_exponents(mtab, all_exponents+n-1);
|
|
Packit |
e4b6da |
free(old_exponents);
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
return p;
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
#endif
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
void
|
|
Packit |
e4b6da |
mtable_set(mtable_t mtab, mtable_key key, void *data)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
int i, e=0;
|
|
Packit |
e4b6da |
struct mtable *p;
|
|
Packit |
e4b6da |
mtable_key k;
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
for(i=0; mtab->exponents[i] != 0; i++)
|
|
Packit |
e4b6da |
e += mtab->exponents[i];
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
p = mtab;
|
|
Packit |
e4b6da |
k = key;
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
for(;;) {
|
|
Packit |
e4b6da |
if(p->exponents[1] == 0) {
|
|
Packit |
e4b6da |
p->slots[k] = data;
|
|
Packit |
e4b6da |
return;
|
|
Packit |
e4b6da |
} else {
|
|
Packit |
e4b6da |
e -= p->exponents[0];
|
|
Packit |
e4b6da |
i = mtable_left_index(k, e);
|
|
Packit |
e4b6da |
k = mtable_right_index(k, e);
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
if(p->slots[i] == NULL)
|
|
Packit |
e4b6da |
p->slots[i] = mtable_new2(p->exponents+1);
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
p = p->slots[i];
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
void
|
|
Packit |
e4b6da |
*mtable_get(mtable_t mtab, mtable_key key)
|
|
Packit |
e4b6da |
{
|
|
Packit |
e4b6da |
int i, e=0;
|
|
Packit |
e4b6da |
struct mtable *p;
|
|
Packit |
e4b6da |
mtable_key k;
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
for(i=0; mtab->exponents[i] != 0; i++)
|
|
Packit |
e4b6da |
e += mtab->exponents[i];
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
p = mtab;
|
|
Packit |
e4b6da |
k = key;
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
while(p != NULL) {
|
|
Packit |
e4b6da |
if(p->exponents[1] == 0) {
|
|
Packit |
e4b6da |
return p->slots[k];
|
|
Packit |
e4b6da |
} else {
|
|
Packit |
e4b6da |
e -= p->exponents[0];
|
|
Packit |
e4b6da |
i = mtable_left_index(k, e);
|
|
Packit |
e4b6da |
k = mtable_right_index(k, e);
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
p = p->slots[i];
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
}
|
|
Packit |
e4b6da |
|
|
Packit |
e4b6da |
return NULL;
|
|
Packit |
e4b6da |
}
|