|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 5934 (0x172e) Types: TextFile Names: »turbo_load.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/quipu/turbo_load.c«
/* turbo_load.c - Quickly check for duplicate RDN's (from Tim Howes) */ #ifndef lint static char *rcsid = "$Header: /f/osi/quipu/RCS/turbo_load.c,v 7.0 89/11/23 22:20:57 mrose Rel $"; #endif /* * $Header: /f/osi/quipu/RCS/turbo_load.c,v 7.0 89/11/23 22:20:57 mrose Rel $ * * * $Log: turbo_load.c,v $ * Revision 7.0 89/11/23 22:20:57 mrose * Release 6.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ #include <sys/types.h> #include <sys/stat.h> #include "quipu/util.h" #include "quipu/entry.h" #include "quipu/malloc.h" extern LLog * log_dsap; extern int turbo_size; extern int turbo_name_size; static struct node { char *name; struct node *left; struct node *right; int bf; }; static struct node *node_heap; static struct node *node_next; static char *name_heap; static char *name_next; static struct node *root; static long count; static long comparisons; static long entries; turbo_start(file) FILE *file; { struct stat buf; int save_heap; if ( fstat(fileno(file), &buf) != 0 ) { LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: could not get filesize")); return FALSE; } /* * This is a heuristic based on some edb file sizes at * UM. If you find this isn't enough, try using * a smaller turbo_size (in quiputailor). This should * eventually be fixed to malloc more if the heuristic * turns out not to be enough. */ entries = (buf.st_size) / turbo_size; if ( entries < 100 ) entries = 100; save_heap = mem_heap; GENERAL_HEAP node_heap = (struct node *) calloc( (unsigned)entries, sizeof(struct node) ); node_next = node_heap; name_heap = (char *) calloc( (unsigned)entries, (unsigned)turbo_name_size ); name_next = name_heap; mem_heap = save_heap; root = 0; count = 0; comparisons = 0; return TRUE; } turbo_insert(name) RDN name; { int taller; if ( ++count >= entries ) { if (count == entries) LLOG (log_dsap,LLOG_EXCEPTIONS,("turbo botch - decrease turbo_size (currently %d - %d entries read)",turbo_size,entries)); /* should realloc */ return OK; } if (strlen ((char *) name->rdn_av.av_struct) >= turbo_name_size) { LLOG (log_dsap,LLOG_EXCEPTIONS,("turbo botch - increase turbo_name_size (%d required for '%s', currently %d)", strlen ((char *) name->rdn_av.av_struct), (char *)name->rdn_av.av_struct, turbo_name_size)); /* should realloc */ return OK; } return (avl_insert(&root, (char *) name->rdn_av.av_struct, &taller)); } #define LH -1 #define EH 0 #define RH 1 #define ROTATERIGHT(x) { struct node *tmp;\ if ( *x == NULL || (*x)->left == NULL ) {\ (void) printf("RR error\n"); exit(1); \ }\ tmp = (*x)->left;\ (*x)->left = tmp->right;\ tmp->right = *x;\ *x = tmp;\ } #define ROTATELEFT(x) { struct node *tmp;\ if ( *x == NULL || (*x)->right == NULL ) {\ (void) printf("RL error\n"); exit(1); \ }\ tmp = (*x)->right;\ (*x)->right = tmp->left;\ tmp->left = *x;\ *x = tmp;\ } static avl_insert(iroot, name, taller) struct node **iroot; char *name; int *taller; { int rc, cmp, tallersub; struct node *l, *r; comparisons++; if ( *iroot == 0 ) { *iroot = node_next++; (*iroot)->left = 0; (*iroot)->right = 0; (*iroot)->bf = 0; (*iroot)->name = name_next; while ( *(name_next++) = *(name++) ); *taller = 1; return (OK); } cmp = strcmp(name, (*iroot)->name); /* equal - duplicate name */ if ( cmp == 0 ) { *taller = 0; return (NOTOK); } /* go right */ else if ( cmp > 0 ) { rc = avl_insert(&((*iroot)->right), name, &tallersub); if (tallersub) switch ((*iroot)->bf) { case LH : /* left high - balance is restored */ (*iroot)->bf = EH; *taller = 0; break; case EH : /* equal height - now right heavy */ (*iroot)->bf = RH; *taller = 1; break; case RH : /* right heavy to start - right balance */ r = (*iroot)->right; switch (r->bf) { case LH : /* double rotation left */ l = r->left; switch (l->bf) { case LH : (*iroot)->bf = EH; r->bf = RH; break; case EH : (*iroot)->bf = EH; r->bf = EH; break; case RH : (*iroot)->bf = LH; r->bf = EH; break; } l->bf = EH; ROTATERIGHT((&r)) (*iroot)->right = r; ROTATELEFT(iroot) *taller = 0; break; case EH : /* This should never happen */ break; case RH : /* single rotation left */ (*iroot)->bf = EH; r->bf = EH; ROTATELEFT(iroot) *taller = 0; break; } break; } else *taller = 0; } /* go left */ else { rc = avl_insert(&((*iroot)->left), name, &tallersub); if (tallersub) switch ((*iroot)->bf) { case LH : /* left high to start - left balance */ l = (*iroot)->left; switch (l->bf) { case LH : /* single rotation right */ (*iroot)->bf = EH; l->bf = EH; ROTATERIGHT(iroot) *taller = 0; break; case EH : /* this should never happen */ break; case RH : /* double rotation right */ r = l->right; switch (r->bf) { case LH : (*iroot)->bf = RH; l->bf = EH; break; case EH : (*iroot)->bf = EH; l->bf = EH; break; case RH : (*iroot)->bf = EH; l->bf = LH; break; } r->bf = EH; ROTATELEFT((&l)) (*iroot)->left = l; ROTATERIGHT(iroot) *taller = 0; break; } break; case EH : /* equal height - now left heavy */ (*iroot)->bf = LH; *taller = 1; break; case RH : /* right high - balance is restored */ (*iroot)->bf = EH; *taller = 0; break; } else *taller = 0; } return(rc); } turbo_end() { DLOG (log_dsap,LLOG_DEBUG,("turbo %d entries unused",entries - count)); free(name_heap); free((char *)node_heap); }