Blame utf8trans/mtable.c

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
}