Tree* ParseBuildTree(List* L,Err* E){ if (L==NULL) return NULL; List* Lold=L; Tree* Told; Tree* T=TreeInit(); ParseStates state=CMD; ParseMorpheme("(",&state,&T); while (state!=PARSEERROR && L!=NULL){ Lold=L; ParseMorpheme((char*)L->data,&state,&T); L=L->next; } ParseMorpheme(")",&state,&T); if (state==PARSEERROR){ if (T!=NULL) while (T->parent!=NULL) T=T->parent; TreeFree(T); E->pres=1; E->err=realloc(E->err,(50+strlen(Lold->data)*sizeof(char))); strcpy(E->err,"Syntax error near: \0"); strcpy((E->err)+strlen(E->err),(char*)Lold->data); return NULL; } Told=T; while (T->parent!=NULL) T=T->parent; ParseTreeFixNULL(T); return T; }
int HuffmanTreeBuildExplicit(HuffmanTree* const tree, const int* const code_lengths, const int* const codes, const int* const symbols, int max_symbol, int num_symbols) { int ok = 0; int i; assert(tree != NULL); assert(code_lengths != NULL); assert(codes != NULL); assert(symbols != NULL); // Initialize the tree. Will fail if num_symbols = 0. if (!TreeInit(tree, num_symbols)) return 0; // Add symbols one-by-one. for (i = 0; i < num_symbols; ++i) { if (codes[i] != NON_EXISTENT_SYMBOL) { if (symbols[i] < 0 || symbols[i] >= max_symbol) { goto End; } if (!TreeAddSymbol(tree, symbols[i], codes[i], code_lengths[i])) { goto End; } } } ok = 1; End: ok = ok && IsFull(tree); if (!ok) HuffmanTreeRelease(tree); return ok; }
int main(void){ int i=0, array[]={34,12,65,23,2,100,120}; Node* root = NULL; root = TreeInit(49); for (i=0;i<7;++i){ NodeInsert(root,array[i]); } InorderPrintTree(root); putchar('\n'); PostorderPrintTree(root); printf("\nAddress of node with key=13 is %p\n",(void *)TreeSearch(root,13)); printf("Minimum : %d \n", (TreeMinimum(root))->key); printf("Maximum : %d \n", (TreeMaximum(root))->key); printf("Treesize : %d \n", TreeSize(root)); printf("Max depth : %d \n", MaxDepth(root)); TreeDelete(root); getchar(); return 0; }
int HuffmanTreeBuildImplicit(HuffmanTree* const tree, const int* const code_lengths, int code_lengths_size) { int symbol; int num_symbols = 0; int root_symbol = 0; assert(tree != NULL); assert(code_lengths != NULL); // Find out number of symbols and the root symbol. for (symbol = 0; symbol < code_lengths_size; ++symbol) { if (code_lengths[symbol] > 0) { // Note: code length = 0 indicates non-existent symbol. ++num_symbols; root_symbol = symbol; } } // Initialize the tree. Will fail for num_symbols = 0 if (!TreeInit(tree, num_symbols)) return 0; // Build tree. if (num_symbols == 1) { // Trivial case. const int max_symbol = code_lengths_size; if (root_symbol < 0 || root_symbol >= max_symbol) { HuffmanTreeRelease(tree); return 0; } return TreeAddSymbol(tree, root_symbol, 0, 0); } else { // Normal case. int ok = 0; // Get Huffman codes from the code lengths. int* const codes = (int*)WebPSafeMalloc((uint64_t)code_lengths_size, sizeof(*codes)); if (codes == NULL) goto End; if (!HuffmanCodeLengthsToCodes(code_lengths, code_lengths_size, codes)) { goto End; } // Add symbols one-by-one. for (symbol = 0; symbol < code_lengths_size; ++symbol) { if (code_lengths[symbol] > 0) { if (!TreeAddSymbol(tree, symbol, codes[symbol], code_lengths[symbol])) { goto End; } } } ok = 1; End: free(codes); ok = ok && IsFull(tree); if (!ok) HuffmanTreeRelease(tree); return ok; } }
Tree* TreeInsert(Tree** tree, void* element, Tree* parent, int (*comp)(const void*, const void*)) { if ( !*tree ) { TreeInit(tree); (*tree)->parent = parent; (*tree)->data = element; return *tree; } else { if ( (*comp)(element, (*tree)->data) < 0 ) { return TreeInsert(&(*tree)->left, element, *tree, comp); } else { return TreeInsert(&(*tree)->right, element, *tree, comp); } } }
static Compare SplaySplitDown(SplayStateStruct *stateReturn, SplayTree splay, TreeKey key, TreeCompareFunction compare) { TreeStruct sentinel; Tree middle, leftLast, rightFirst, leftPrev, rightNext; Compare cmp; AVERT(SplayTree, splay); AVER(FUNCHECK(compare)); AVER(!SplayTreeIsEmpty(splay)); AVER(!SplayHasUpdate(splay)); TreeInit(&sentinel); leftLast = &sentinel; rightFirst = &sentinel; middle = SplayTreeRoot(splay); for (;;) { cmp = compare(middle, key); switch(cmp) { default: NOTREACHED; /* defensive fall-through */ case CompareEQUAL: goto stop; case CompareLESS: if (!TreeHasLeft(middle)) goto stop; middle = SplayZig(middle, &rightFirst, &rightNext); cmp = compare(middle, key); switch(cmp) { default: NOTREACHED; /* defensive fall-through */ case CompareEQUAL: goto stop; case CompareLESS: if (!TreeHasLeft(middle)) goto stop; middle = SplayZigZig(middle, &rightFirst, rightNext); break; case CompareGREATER: if (!TreeHasRight(middle)) goto stop; middle = SplayZag(middle, &leftLast, &leftPrev); break; } break; case CompareGREATER: if (!TreeHasRight(middle)) goto stop; middle = SplayZag(middle, &leftLast, &leftPrev); cmp = compare(middle, key); switch(cmp) { default: NOTREACHED; /* defensive fall-through */ case CompareEQUAL: goto stop; case CompareGREATER: if (!TreeHasRight(middle)) goto stop; middle = SplayZagZag(middle, &leftLast, leftPrev); break; case CompareLESS: if (!TreeHasLeft(middle)) goto stop; middle = SplayZig(middle, &rightFirst, &rightNext); break; } break; } } stop: stateReturn->middle = middle; stateReturn->left = TreeRight(&sentinel); stateReturn->leftLast = leftLast == &sentinel ? TreeEMPTY : leftLast; stateReturn->right = TreeLeft(&sentinel); stateReturn->rightFirst = rightFirst == &sentinel ? TreeEMPTY : rightFirst; return cmp; }
Res ChunkInit(Chunk chunk, Arena arena, Addr base, Addr limit, Size reserved, BootBlock boot) { Size size; Count pages; Shift pageShift; Size pageTableSize; Addr allocBase; void *p; Res res; /* chunk is supposed to be uninitialized, so don't check it. */ AVERT(Arena, arena); AVER(base != NULL); AVER(AddrIsAligned(base, ArenaGrainSize(arena))); AVER(base < limit); AVER(AddrIsAligned(limit, ArenaGrainSize(arena))); AVERT(BootBlock, boot); chunk->serial = (arena->chunkSerial)++; chunk->arena = arena; RingInit(&chunk->arenaRing); chunk->pageSize = ArenaGrainSize(arena); chunk->pageShift = pageShift = SizeLog2(chunk->pageSize); chunk->base = base; chunk->limit = limit; chunk->reserved = reserved; size = ChunkSize(chunk); /* .overhead.pages: Chunk overhead for the page allocation table. */ chunk->pages = pages = size >> pageShift; res = BootAlloc(&p, boot, (size_t)BTSize(pages), MPS_PF_ALIGN); if (res != ResOK) goto failAllocTable; chunk->allocTable = p; pageTableSize = SizeAlignUp(pages * sizeof(PageUnion), chunk->pageSize); chunk->pageTablePages = pageTableSize >> pageShift; res = Method(Arena, arena, chunkInit)(chunk, boot); if (res != ResOK) goto failClassInit; /* @@@@ Is BootAllocated always right? */ /* Last thing we BootAlloc'd is pageTable. We requested pageSize */ /* alignment, and pageTableSize is itself pageSize aligned, so */ /* BootAllocated should also be pageSize aligned. */ AVER(AddrIsAligned(BootAllocated(boot), chunk->pageSize)); chunk->allocBase = (Index)(BootAllocated(boot) >> pageShift); /* Init allocTable after class init, because it might be mapped there. */ BTResRange(chunk->allocTable, 0, pages); /* Check that there is some usable address space remaining in the chunk. */ allocBase = PageIndexBase(chunk, chunk->allocBase); AVER(allocBase < chunk->limit); /* Add the chunk's free address space to the arena's freeLand, so that we can allocate from it. */ if (arena->hasFreeLand) { res = ArenaFreeLandInsert(arena, allocBase, chunk->limit); if (res != ResOK) goto failLandInsert; } TreeInit(&chunk->chunkTree); chunk->sig = ChunkSig; AVERT(Chunk, chunk); ArenaChunkInsert(arena, chunk); return ResOK; failLandInsert: Method(Arena, arena, chunkFinish)(chunk); /* .no-clean: No clean-ups needed past this point for boot, as we will discard the chunk. */ failClassInit: failAllocTable: return res; }
int main(int argc, char **argv) { if (argc < 3) { PrintUsage(stderr, argv[0]); return -1; } if (!strcmp(argv[1], "create")) { if (argc < 4) { fprintf(stderr, "ERROR: incorrect create usage\n"); return -2; } char *outbfile = argv[2]; int n = atoi(argv[3]); /* Calculate btree size */ int depth = CalcMinimumDepth(n); int sz = CalcTreeSize2(n, depth); fprintf(stderr, "n = %i, depth = %i, size = %i\n", n, depth, sz); /* Create memory buffer */ mem = (char *) malloc(sz + 1); mem[sz] = 123; // Magic Marker to detect overflow memSize = sz; /* Init top node */ BlockAddrT top = AllocBlock(0x0); Node topNode; NodeInit(&topNode); topNode.depth = depth - 1; // total depth vs depth(rank?) of this node NodeSave(&topNode, top); BgTree tree; tree.topNode = top; /* Read in data */ KeyT highestKey = 0; for (int i=0; i<n; i++) { KeyT key; BlockAddrT item; int res = fscanf(stdin, "%x\t%x", &key, &item); assert(res == 2); if (key < highestKey) { fprintf(stderr, "ERROR: Key out of order on line %i. Input must be sorted!\n", i+1); return -3; } highestKey = key; //printf("GOT %i %i\n", key, item); TreeAppend(tree, key, item); } /* Set keys for non-leaf nodes */ //NodeVisitDFS(&SetKeysVisitor, top); /* Write memory to file */ assert(mem[sz] == 123); fprintf(stderr, "MEM: %i of %i allocated was used\n", memLast, memSize); FILE *f = fopen(outbfile, "wb"); if (!f) { fprintf(stderr, "ERROR: Failed to open file %s for writing\n", outbfile); return -9; } int res = fwrite(mem, 1, memLast, f); if (res != memLast) { fprintf(stderr, "ERROR: Could not write all data to file %s\n", outbfile); return -4; } fclose(f); } // end of "create" command if (!strcmp(argv[1], "search")) { if (argc < 4) { fprintf(stderr, "ERROR: search usage incorrect, not enough arguments\n"); return -11; } FILE *blobfile = 0x0; if (argc > 4) { blobfile = fopen(argv[4],"rb"); if (!blobfile) { fprintf(stderr, "ERROR: failed to open Blob File %s\n", argv[4]); return -19; } } char *schema=0x0; if (argc > 5) { schema = argv[5]; } char *inbfile = argv[2]; KeyT key; int res; if (argv[3][0] == 'S') { key = CalcCRC(&argv[3][1], strlen(&argv[3][1])); //fprintf(stderr, "CRC32=%x for %s len=%i\n", key, &argv[3][1], (int) strlen(&argv[3][1])); printf("%x", key); if (mem) free(mem); exit(0); } else { // assume hex res = sscanf(argv[3], "%x", &key); if (res != 1) { fprintf(stderr, "ERROR: Unable to parse query key argument %s\n", argv[3]); return -12; } } if (LoadBGT(inbfile) != 0) return -99; /* Perform Search */ BAT outParent; int outIndex; BAT found_temp; BAT found = FindInternal(0, key, &outParent, &outIndex); while (found != BAInvalid) { // if (found == BAInvalid) { // printf("%x NOT FOUND!\n", key); // } else { //printf("%x\t%08x", key, found); if (schema && blobfile) { for (char *p = &schema[0]; *p; ++p) { if ((*p == 's') || (*p == 'K')) { char buf[2000000]; fseek(blobfile, found, SEEK_SET); int sz = UnpackStringFromFile(blobfile, buf, 2000000); if (sz < 0) { fprintf(stderr, "ERROR: Failed to read String from blob file\n"); return -20; } found += sz; buf[sz] = 0x0; // not null terminated by default printf("\t%s", buf); } else if (*p == 'i') { int32_t v; fseek(blobfile, found, SEEK_SET); v = UnpackIntFromFile(blobfile); ERRORassert(); found += 4; //printf("\t%i", v); } else if ((*p == 'I') || (*p == 'x') || (*p == 'X')) { uint32_t v; fseek(blobfile, found, SEEK_SET); v = UnpackUIntFromFile(blobfile); ERRORassert(); //if (*p == 'I') // printf("\t%u", v); //else // printf("\t%x", v); found += 4; } else { fprintf(stderr, "ERROR: Unsupported schema character '%c'\n", *p); return -23; } } } printf("\n"); // found_temp = NodeNextLeaf(NodeParent(found), found); //found_temp = FindInternal(0, key, &outParent, &outIndex); key++; found_temp = FindInternal(0, key, &outParent, &outIndex); found = found_temp; } if (blobfile) fclose(blobfile); } else if (!strcmp(argv[1],"printtree")) { if (LoadBGT(argv[2]) != 0) { printf("Error Loading BGT\n"); return -99; } BgTree dummy; TreeInit(&dummy,0x0); NodeVisitDFS(dummy, &PrintVisitor, 0); } if (mem) free(mem); }
void ParseMorpheme(char* S, ParseStates* state, Tree** T){ static char* redirop=NULL; redirop=myrealloc(redirop,3*sizeof(char)); Tree* newT=NULL; switch (*state){ case CMD:{ switch (ParseGetTokenClass(S)){ case TEXT: StringPut(&((*T)->cmd),S); (*T)->type=LINK_COMMAND; *state=ARGS; break; case SUBSHELL_BEGIN: newT=TreeInit(); newT->type=LINK_SUBSHELL; newT->left=(*T); newT->parent=(*T)->parent; (*T)->parent=newT; if (newT->parent!=NULL){ if (newT->parent->left==(*T)) newT->parent->left=newT; if (newT->parent->right==(*T)) newT->parent->right=newT; } *state=CMD; break; case SUBSHELL_END: while((*T)!=NULL &&((*T)->type!=LINK_SUBSHELL)) *T=(*T)->parent; if (*T==NULL) *state=PARSEERROR; else *state=AFTERSUBSHELL; break; default: *state=PARSEERROR; break; } break; } case ARGS:{ switch (ParseGetTokenClass(S)){ case TEXT: ListAdd(&((*T)->args),S); *state=ARGS; break; case REDIRECT: strcpy(redirop,S); *state=REDIR; break; case OPER: newT=TreeInit(); newT->type=OperatorType(S); if (newT->type==LINK_AND || newT->type==LINK_OR){ while ((*T)->parent->type!=LINK_SUBSHELL) (*T)=(*T)->parent; } if (newT->type==LINK_BACKGROUND || newT->type==LINK_SEMICOLON){ while ((*T)->parent->type!=LINK_SUBSHELL && (*T)->parent->type!=LINK_AND && (*T)->parent->type!=LINK_OR) (*T)=(*T)->parent; } if (newT->type==LINK_BACKGROUND || newT->type==LINK_SEMICOLON){ while ((*T)->parent->type!=LINK_SUBSHELL && (*T)->parent->type!=LINK_AND && (*T)->parent->type!=LINK_OR) (*T)=(*T)->parent; } newT->parent=(*T)->parent; if (newT->parent!=NULL) { if (newT->parent->left==(*T)) newT->parent->left=newT; if (newT->parent->right==(*T)) newT->parent->right=newT; } (*T)->parent=newT; newT->left=(*T); newT->right=TreeInit(); newT->right->parent=newT; *T=newT->right; *state=CMD; break; case SUBSHELL_END: while((*T)!=NULL &&((*T)->type!=LINK_SUBSHELL)) *T=(*T)->parent; if (*T==NULL) *state=PARSEERROR; else *state=AFTERSUBSHELL; break; default: *state=PARSEERROR; } break; } case REDIR:{ switch (ParseGetTokenClass(S)){ case TEXT: if (!strcmp(redirop,">")) StringPut(&((*T)->out),S); if (!strcmp(redirop,">>")) StringPut(&((*T)->append),S); if (!strcmp(redirop,"<")) StringPut(&((*T)->in),S); *state=ARGS; break; default: *state=PARSEERROR; } break; } case AFTERSUBSHELL:{ switch (ParseGetTokenClass(S)){ case OPER: newT=TreeInit(); newT->type=OperatorType(S); if (newT->type==LINK_AND || newT->type==LINK_OR){ while ((*T)->parent->type!=LINK_SUBSHELL) (*T)=(*T)->parent; } if (newT->type==LINK_BACKGROUND || newT->type==LINK_SEMICOLON){ while ((*T)->parent->type!=LINK_SUBSHELL && (*T)->parent->type!=LINK_AND && (*T)->parent->type!=LINK_OR) (*T)=(*T)->parent; } if (newT->type==LINK_BACKGROUND || newT->type==LINK_SEMICOLON){ while ((*T)->parent->type!=LINK_SUBSHELL && (*T)->parent->type!=LINK_AND && (*T)->parent->type!=LINK_OR) (*T)=(*T)->parent; } newT->parent=(*T)->parent; if (newT->parent!=NULL) { if (newT->parent->left==(*T)) newT->parent->left=newT; if (newT->parent->right==(*T)) newT->parent->right=newT; } (*T)->parent=newT; newT->left=(*T); newT->right=TreeInit(); newT->right->parent=newT; *T=newT->right; *state=CMD; break; case REDIRECT: *state=REDIR; break; case SUBSHELL_END: *T=(*T)->parent; while((*T)!=NULL &&((*T)->type!=LINK_SUBSHELL)) *T=(*T)->parent; if (*T==NULL) *state=PARSEERROR; else *state=AFTERSUBSHELL; break; default: *state=PARSEERROR; } break; } default: *state=PARSEERROR; } }