Annotation of 43BSDReno/contrib/isode-beta/quipu/turbo_load.c, revision 1.1

1.1     ! root        1: /* turbo_load.c - Quickly check for duplicate RDN's (from Tim Howes) */
        !             2: 
        !             3: #ifndef        lint
        !             4: static char *rcsid = "$Header: /f/osi/quipu/RCS/turbo_load.c,v 7.1 90/07/09 14:46:48 mrose Exp $";
        !             5: #endif
        !             6: 
        !             7: /* 
        !             8:  * $Header: /f/osi/quipu/RCS/turbo_load.c,v 7.1 90/07/09 14:46:48 mrose Exp $
        !             9:  *
        !            10:  *
        !            11:  * $Log:       turbo_load.c,v $
        !            12:  * Revision 7.1  90/07/09  14:46:48  mrose
        !            13:  * sync
        !            14:  * 
        !            15:  * Revision 7.0  89/11/23  22:20:57  mrose
        !            16:  * Release 6.0
        !            17:  * 
        !            18:  */
        !            19: 
        !            20: /*
        !            21:  *                               NOTICE
        !            22:  *
        !            23:  *    Acquisition, use, and distribution of this module and related
        !            24:  *    materials are subject to the restrictions of a license agreement.
        !            25:  *    Consult the Preface in the User's Manual for the full terms of
        !            26:  *    this agreement.
        !            27:  *
        !            28:  */
        !            29: 
        !            30: #include "quipu/config.h"
        !            31: #include "quipu/util.h"
        !            32: #include "quipu/entry.h"
        !            33: #include "quipu/malloc.h"
        !            34: #include <sys/stat.h>
        !            35: #ifdef TURBO_DISK
        !            36: #include "../../gdbm-1.3/gdbmdefs.h"
        !            37: #endif
        !            38: 
        !            39: extern LLog * log_dsap;
        !            40: 
        !            41: extern int turbo_size;
        !            42: extern int turbo_name_size;
        !            43: 
        !            44: struct node {
        !            45:        char *name;
        !            46:        struct node *left;
        !            47:        struct node *right;
        !            48:        int bf;
        !            49: };
        !            50: 
        !            51: static struct node *node_heap;
        !            52: static struct node *node_next;
        !            53: 
        !            54: static char *name_heap;
        !            55: static char *name_next;
        !            56: 
        !            57: static struct node *root;
        !            58: static long count;
        !            59: static long comparisons;
        !            60: static long entries;
        !            61: 
        !            62: turbo_start(file)
        !            63: #ifdef TURBO_DISK
        !            64: gdbm_file_info *file;
        !            65: #else
        !            66: FILE           *file;
        !            67: #endif
        !            68: {
        !            69:        struct stat buf;
        !            70:        int save_heap;
        !            71: 
        !            72: #ifdef TURBO_DISK
        !            73:        if ( fstat(file->desc, &buf) != 0 ) {
        !            74: #else
        !            75:        if ( fstat(fileno(file), &buf) != 0 ) {
        !            76: #endif
        !            77:                LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: could not get filesize"));
        !            78:                return FALSE;
        !            79:        }
        !            80: 
        !            81:        /* 
        !            82:         * This is a heuristic based on some edb file sizes at
        !            83:         * UM.  If you find this isn't enough, try using
        !            84:         * a smaller turbo_size (in quiputailor).  This should
        !            85:         * eventually be fixed to malloc more if the heuristic
        !            86:         * turns out not to be enough.
        !            87:        */
        !            88:        entries = (buf.st_size) / turbo_size;
        !            89:        if ( entries < 100 ) entries = 100;
        !            90: 
        !            91:        save_heap = mem_heap;
        !            92:        GENERAL_HEAP;
        !            93:        node_heap = (struct node *) calloc( (unsigned)entries, sizeof(struct node) );
        !            94:        node_next = node_heap;
        !            95:        name_heap = (char *) calloc( (unsigned)entries, (unsigned)turbo_name_size );
        !            96:        name_next = name_heap;
        !            97:        mem_heap = save_heap;
        !            98:        root = 0;
        !            99:        count = 0;
        !           100:        comparisons = 0;
        !           101: 
        !           102:        mem_heap = save_heap;
        !           103:        return TRUE;
        !           104: }
        !           105: 
        !           106: #define LH     -1
        !           107: #define EH     0
        !           108: #define RH     1
        !           109: #define ROTATERIGHT(x) { struct node *tmp;\
        !           110:        if ( *x == NULL || (*x)->left == NULL ) {\
        !           111:                (void) printf("RR error\n"); exit(1); \
        !           112:        }\
        !           113:        tmp = (*x)->left;\
        !           114:        (*x)->left = tmp->right;\
        !           115:        tmp->right = *x;\
        !           116:        *x = tmp;\
        !           117: }
        !           118: #define ROTATELEFT(x)  { struct node *tmp;\
        !           119:        if ( *x == NULL || (*x)->right == NULL ) {\
        !           120:                (void) printf("RL error\n"); exit(1); \
        !           121:        }\
        !           122:        tmp = (*x)->right;\
        !           123:        (*x)->right = tmp->left;\
        !           124:        tmp->left = *x;\
        !           125:        *x = tmp;\
        !           126: }
        !           127: 
        !           128: 
        !           129: static avl_insert(iroot, name, taller)
        !           130: struct node **iroot;
        !           131: char *name;
        !           132: int *taller;
        !           133: {
        !           134:        int rc, cmp, tallersub;
        !           135:        struct node *l, *r;
        !           136: 
        !           137:        comparisons++;
        !           138:        if ( *iroot == 0 ) {
        !           139:                *iroot = node_next++;
        !           140:                (*iroot)->left = 0;
        !           141:                (*iroot)->right = 0;
        !           142:                (*iroot)->bf = 0;
        !           143:                (*iroot)->name = name_next;
        !           144:                while ( *(name_next++) = *(name++) );
        !           145:                *taller = 1;
        !           146:                return (OK);
        !           147:        }
        !           148: 
        !           149:        cmp = strcmp(name, (*iroot)->name);
        !           150:        /* equal - duplicate name */
        !           151:        if ( cmp == 0 ) {
        !           152:                 *taller = 0;
        !           153:                return (NOTOK);
        !           154:        }
        !           155:        /* go right */
        !           156:        else if ( cmp > 0 ) {
        !           157:                rc = avl_insert(&((*iroot)->right), name, &tallersub);
        !           158:                if (tallersub)
        !           159:                        switch ((*iroot)->bf) {
        !           160:                        case LH : /* left high - balance is restored */
        !           161:                                (*iroot)->bf = EH;
        !           162:                                *taller = 0;
        !           163:                                break;
        !           164:                        case EH : /* equal height - now right heavy */
        !           165:                                (*iroot)->bf = RH;
        !           166:                                *taller = 1;
        !           167:                                break;
        !           168:                        case RH : /* right heavy to start - right balance */
        !           169:                                r = (*iroot)->right;
        !           170:                                switch (r->bf) {
        !           171:                                case LH : /* double rotation left */
        !           172:                                        l = r->left;
        !           173:                                        switch (l->bf) {
        !           174:                                        case LH : (*iroot)->bf = EH;
        !           175:                                                  r->bf = RH;
        !           176:                                                  break;
        !           177:                                        case EH : (*iroot)->bf = EH;
        !           178:                                                  r->bf = EH;
        !           179:                                                  break;
        !           180:                                        case RH : (*iroot)->bf = LH;
        !           181:                                                  r->bf = EH;
        !           182:                                                  break;
        !           183:                                        }
        !           184:                                        l->bf = EH;
        !           185:                                        ROTATERIGHT((&r))
        !           186:                                        (*iroot)->right = r;
        !           187:                                        ROTATELEFT(iroot)
        !           188:                                        *taller = 0;
        !           189:                                        break;
        !           190:                                case EH : /* This should never happen */
        !           191:                                        break;
        !           192:                                case RH : /* single rotation left */
        !           193:                                        (*iroot)->bf = EH;
        !           194:                                        r->bf = EH;
        !           195:                                        ROTATELEFT(iroot)
        !           196:                                        *taller = 0;
        !           197:                                        break;
        !           198:                                }
        !           199:                                break;
        !           200:                        }
        !           201:                else
        !           202:                        *taller = 0;
        !           203:        }
        !           204:        /* go left */
        !           205:        else {
        !           206:                rc = avl_insert(&((*iroot)->left), name, &tallersub);
        !           207:                if (tallersub)
        !           208:                        switch ((*iroot)->bf) {
        !           209:                        case LH : /* left high to start - left balance */
        !           210:                                l = (*iroot)->left;
        !           211:                                switch (l->bf) {
        !           212:                                case LH : /* single rotation right */
        !           213:                                        (*iroot)->bf = EH;
        !           214:                                        l->bf = EH;
        !           215:                                        ROTATERIGHT(iroot)
        !           216:                                        *taller = 0;
        !           217:                                        break;
        !           218:                                case EH : /* this should never happen */
        !           219:                                        break;
        !           220:                                case RH : /* double rotation right */
        !           221:                                        r = l->right;
        !           222:                                        switch (r->bf) {
        !           223:                                        case LH : (*iroot)->bf = RH;
        !           224:                                                  l->bf = EH;
        !           225:                                                  break;
        !           226:                                        case EH : (*iroot)->bf = EH;
        !           227:                                                  l->bf = EH;
        !           228:                                                  break;
        !           229:                                        case RH : (*iroot)->bf = EH;
        !           230:                                                  l->bf = LH;
        !           231:                                                  break;
        !           232:                                        }
        !           233:                                        r->bf = EH;
        !           234:                                        ROTATELEFT((&l))
        !           235:                                        (*iroot)->left = l;
        !           236:                                        ROTATERIGHT(iroot)
        !           237:                                        *taller = 0;
        !           238:                                        break;
        !           239:                                }
        !           240:                                break;
        !           241:                        case EH : /* equal height - now left heavy */
        !           242:                                (*iroot)->bf = LH;
        !           243:                                *taller = 1;
        !           244:                                break;
        !           245:                        case RH : /* right high - balance is restored */
        !           246:                                (*iroot)->bf = EH;
        !           247:                                *taller = 0;
        !           248:                                break;
        !           249:                        }
        !           250:                else
        !           251:                        *taller = 0;
        !           252:        }
        !           253:        return(rc);
        !           254: }
        !           255: 
        !           256: turbo_insert(name)
        !           257: RDN name;
        !           258: {
        !           259:        int taller;
        !           260: 
        !           261:        if ( ++count >= entries ) {
        !           262:                if (count == entries)
        !           263:                        LLOG (log_dsap,LLOG_EXCEPTIONS,("turbo botch - decrease turbo_size (currently %d - %d entries read)",turbo_size,entries));
        !           264:                /* should realloc */
        !           265:                return OK;
        !           266:        }
        !           267: 
        !           268:        if (strlen ((char *) name->rdn_av.av_struct) >= turbo_name_size) {
        !           269:                LLOG (log_dsap,LLOG_EXCEPTIONS,("turbo botch - increase turbo_name_size (%d required for '%s', currently %d)",
        !           270:                        strlen ((char *) name->rdn_av.av_struct),
        !           271:                        (char *)name->rdn_av.av_struct, turbo_name_size));
        !           272:                /* should realloc */
        !           273:                return OK;
        !           274:        }
        !           275: 
        !           276:        return (avl_insert(&root, (char *) name->rdn_av.av_struct, &taller));
        !           277: }
        !           278: 
        !           279: turbo_end()
        !           280: {
        !           281:        int save_heap;
        !           282: 
        !           283:        DLOG (log_dsap,LLOG_DEBUG,("turbo %d entries unused",entries - count));
        !           284: 
        !           285:        save_heap = mem_heap;
        !           286:        GENERAL_HEAP;
        !           287: 
        !           288:        free(name_heap);
        !           289:        free((char *)node_heap);
        !           290: 
        !           291:        mem_heap = save_heap;
        !           292: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.