/* Returns the next data item in inorder within the tree being traversed with |trav|, or if there are no more data items returns |0|. */ static Std$Object_t *avl_t_next (struct avl_traverser *trav) { struct avl_node *x; if (trav->avl_generation != trav->avl_table->avl_generation) trav_refresh (trav); x = trav->avl_node; if (x == 0) { return avl_t_first (trav, trav->avl_table); } else if (x->avl_link[1] != 0) { trav->avl_stack[trav->avl_height++] = x; x = x->avl_link[1]; while (x->avl_link[0] != 0) { trav->avl_stack[trav->avl_height++] = x; x = x->avl_link[0]; } } else { struct avl_node *y; do { if (trav->avl_height == 0) { trav->avl_node = 0; return 0; } y = x; x = trav->avl_stack[--trav->avl_height]; } while (y == x->avl_link[1]); } trav->avl_node = x; return x; }
void write_enc(char **glyph_names, struct avl_table *tx_tree, integer fe_objnum) { int i_old, *p; struct avl_traverser t; assert(glyph_names != NULL); assert(tx_tree != NULL); assert(fe_objnum != 0); pdf_begin_dict(fe_objnum, 1); pdf_puts("/Type /Encoding\n"); pdf_printf("/Differences ["); avl_t_init(&t, tx_tree); for (i_old = -2, p = (int *) avl_t_first(&t, tx_tree); p != NULL; p = (int *) avl_t_next(&t)) { if (*p == i_old + 1) /* no gap */ pdf_printf("/%s", glyph_names[*p]); else { if (i_old == -2) pdf_printf("%i/%s", *p, glyph_names[*p]); else pdf_printf(" %i/%s", *p, glyph_names[*p]); } i_old = *p; } pdf_puts("]\n"); pdf_end_dict(); }
extern "C" void fc_solve_dbm_store_offload_pre_cache( fcs_dbm_store_t store, fcs_pre_cache_t * pre_cache ) { leveldb::DB * db; #ifdef FCS_DBM_USE_LIBAVL struct avl_traverser trav; dict_key_t item; #else dnode_t * node; #endif dict_t * kaz_tree; int num_left_in_transaction = MAX_ITEMS_IN_TRANSACTION; leveldb::WriteBatch batch; fcs_pre_cache_key_val_pair_t * kv; db = (leveldb::DB *)store; kaz_tree = pre_cache->kaz_tree; #ifdef FCS_DBM_USE_LIBAVL avl_t_init(&trav, kaz_tree); #endif #ifdef FCS_DBM_USE_LIBAVL for ( item = avl_t_first(&trav, kaz_tree) ; item ; item = avl_t_next(&trav) ) #else for (node = fc_solve_kaz_tree_first(kaz_tree); node ; node = fc_solve_kaz_tree_next(kaz_tree, node) ) #define item (node->dict_key) #endif { kv = (fcs_pre_cache_key_val_pair_t *)(item); leveldb::Slice key((const char *)(kv->key.s+1),kv->key.s[0]); /* We add 1 to the parent and move's length because it includes the * trailing one-char move. * */ leveldb::Slice parent_and_move((const char *)(kv->parent_and_move.s+1),kv->parent_and_move.s[0]+1); batch.Put(key, parent_and_move); if ((--num_left_in_transaction) <= 0) { #define WRITE() assert(db->Write(leveldb::WriteOptions(), &batch).ok()) WRITE(); batch.Clear(); num_left_in_transaction = MAX_ITEMS_IN_TRANSACTION; } } WRITE(); #undef WRITE }
void logicop::EventQueue::swipe4bind(SweepLine& SL, BindCollection& BC) { Event* evt; avl_traverser trav; avl_t_first(&trav,_equeue); while (trav.avl_node != NULL) { evt = (Event*)trav.avl_node->avl_data; SL.set_currentP(evt->evertex()); evt->swipe4bind(SL, BC); avl_t_next(&trav); } }
void write_fontencodings() { fe_entry *fe; struct avl_traverser t; if (fe_tree == NULL) return; avl_t_init(&t, fe_tree); for (fe = (fe_entry *) avl_t_first(&t, fe_tree); fe != NULL; fe = (fe_entry *) avl_t_next(&t)) if (fe->fe_objnum != 0) write_fontencoding(fe); }
/*!This method is actually executing Bentley-Ottman algorithm. It traverses the event queue and calls swipe4cross methods of every Event. It should be noted that the _equeue is dynamically updated with the crossing events by the same swipe4cross methods. \n The method is sensible to the updates in the tree in a wierd way. Program will bomb out here if a new event has not been inserted properly. Some kind of try-catch mechanism should be implemented.*/ void logicop::EventQueue::swipe4cross(SweepLine& SL) { // see the comment around find parameter in the E_compare Event* evt; avl_traverser trav; avl_t_first(&trav,_equeue); while (trav.avl_node != NULL) { evt = (Event*)trav.avl_node->avl_data; SL.set_currentP(evt->evertex()); evt->swipe4cross(SL, _equeue); avl_t_next(&trav); } }
void RefreshACL() { ACL_User *pACL = NULL; struct avl_traverser avl_trans; struct hostent *pTemp; pACL = (ACL_User *) avl_t_first(&avl_trans,ACL_Call_Tree); while(pACL != NULL) { if(*pACL->HostName != '-') { pTemp = GetHostByName(pACL->HostName); if(pTemp != NULL) { pACL->HisAdr.ADDR = IP_FROM_HOSTENT(pTemp,0); } } pACL = (ACL_User *) avl_t_next(&avl_trans); } }
// ACL format: // <"allow"|"deny>"<tab><callsign><tab><hostname/IP Adr><tab><password><tab> // <Name/Location> // // The callsign field is required and should be entered in upper case without // any suffix (-R or -L). Stations are allowed/denied based on the base // callsign. // // hostname can be a numeric IP address, actual resolvable hostname or "-" for // no hostname // // The password can be "-" for no password or the actual password. The password // may not contain spaces or tabs. // // The Name/location field is free text and extends to the end of the line. // If it is desired to display <callsign>-R or <callsign>-L on the Echolink // station list start the name/location field with "-R" or "-L". // void SaveACL() { struct avl_traverser avl_trans; ACL_User *pACL; char *cp; FILE *fp = NULL; char AclFilename[80]; snprintf(AclFilename,sizeof(AclFilename),"%s." ACL_FILENAME_EXT,AppName); if((fp = fopen(AclFilename,"w")) == NULL) { LOG_ERROR(("SaveACL(): Unable to open ACL file for write.\n")); return; } pACL = (ACL_User *) avl_t_first(&avl_trans,ACL_Call_Tree); while(pACL != NULL) { if(pACL->CallPlus == NULL) { cp = NULL; } else if((cp = strchr(pACL->CallPlus,'-')) == NULL) { cp = strchr(pACL->CallPlus,' '); if(cp != NULL) { // Skip the blank cp++; } } fprintf(fp,"%s\t%s\t%s\t%s\t%s\n", pACL->bAuthorized ? "allow" : "deny", pACL->Callsign, pACL->HostName, pACL->Password, cp == NULL ? "" : cp); pACL = (ACL_User *) avl_t_next(&avl_trans); } fclose(fp); }
void LoadACL() { char Line[80]; char *Allow; ACL_User *pACL = NULL; ACL_User *pNextACL = NULL; struct avl_traverser avl_trans; char *WhiteSpace = "\t\n "; int LineNum = 0; FILE *fp = NULL; ACL_User ACL_New; struct stat FileStats; char AclFilename[80]; snprintf(AclFilename,sizeof(AclFilename),"%s." ACL_FILENAME_EXT,AppName); if((fp = fopen(AclFilename,"r")) == NULL) { if(stat(AclFilename,&FileStats) == 0) { // The ACL file exists but we couldn't open it, complain LOG_ERROR(("LoadACL(): Unable to open ACL file.\n")); } return; } memset(&ACL_New,0,sizeof(ACL_New)); ACL_New.bRefreshed = TRUE; while(fgets(Line,sizeof(Line),fp) != NULL) { LineNum++; Allow = strtok(Line,WhiteSpace); if(Allow == NULL || *Allow == '#' || *Allow == ';') { // Empty line or comment continue; } if(STRCMP(Allow,"allow") == 0) { ACL_New.bAuthorized = TRUE; } else if(STRCMP(Allow,"deny") == 0) { ACL_New.bAuthorized = FALSE; } else { // Invalid line LOG_WARN(("LoadACL(): Ignoring line %d, invalid action \"%s\".\n", LineNum,Allow)); continue; } ACL_New.Callsign = strtok(NULL,WhiteSpace); if(ACL_New.Callsign == NULL) { // Invalid line LOG_WARN(("LoadACL(): Ignoring line %d, callsign missing.\n",LineNum)); continue; } if((ACL_New.HostName = strtok(NULL,WhiteSpace)) == NULL) { LOG_WARN(("LoadACL(): Ignoring line %d, hostname missing.\n",LineNum)); continue; } if((ACL_New.Password = strtok(NULL,WhiteSpace)) == NULL) { LOG_WARN(("LoadACL(): Ignoring line %d, password missing.\n",LineNum)); continue; } ACL_New.CallPlus = strtok(NULL,"\n"); // Skip any leading whitespace if(ACL_New.CallPlus != NULL) { while(*ACL_New.CallPlus && isspace(*ACL_New.CallPlus)) { ACL_New.CallPlus++; } } if(!ACLAddUser(&ACL_New)) { LOG_WARN(("LoadACL(): Ignoring line %d, unable to resolve " "hostname \"%s\".\n",LineNum,ACL_New.HostName)); } } fclose(fp); // Remove any old entries from tree pNextACL = (ACL_User *) avl_t_first(&avl_trans,ACL_Call_Tree); while((pACL = pNextACL) != NULL) { // NB: Get the next user now in case we deleted the current user pNextACL = (ACL_User *) avl_t_next(&avl_trans); if(!pACL->bRefreshed) { DeleteACLUser(pACL); } pACL->bRefreshed = FALSE; } }
void *stSortedSet_getFirst(stSortedSet *items) { struct avl_traverser traverser; avl_t_init(&traverser, items->sortedSet); return avl_t_first(&traverser, items->sortedSet); }
/* Checks that |tree| is well-formed and verifies that the values in |array[]| are actually in |tree|. There must be |n| elements in |array[]| and |tree|. Returns nonzero only if no errors detected. */ static int verify_tree (struct avl_table *tree, int array[], size_t n) { int okay = 1; /* Check |tree|'s bst_count against that supplied. */ if (avl_count (tree) != n) { printf (" Tree count is %lu, but should be %lu.\n", (unsigned long) avl_count (tree), (unsigned long) n); okay = 0; } if (okay) { /* Recursively verify tree structure. */ size_t count; int height; recurse_verify_tree (tree->avl_root, &okay, &count, 0, INT_MAX, &height); if (count != n) { printf (" Tree has %lu nodes, but should have %lu.\n", (unsigned long) count, (unsigned long) n); okay = 0; } } if (okay) { /* Check that all the values in |array[]| are in |tree|. */ size_t i; for (i = 0; i < n; i++) if (avl_find (tree, &array[i]) == NULL) { printf (" Tree does not contain expected value %d.\n", array[i]); okay = 0; } } if (okay) { /* Check that |avl_t_first()| and |avl_t_next()| work properly. */ struct avl_traverser trav; size_t i; int prev = -1; int *item; for (i = 0, item = avl_t_first (&trav, tree); i < 2 * n && item != NULL; i++, item = avl_t_next (&trav)) { if (*item <= prev) { printf (" Tree out of order: %d follows %d in traversal\n", *item, prev); okay = 0; } prev = *item; } if (i != n) { printf (" Tree should have %lu items, but has %lu in traversal\n", (unsigned long) n, (unsigned long) i); okay = 0; } } if (okay) { /* Check that |avl_t_last()| and |avl_t_prev()| work properly. */ struct avl_traverser trav; size_t i; int next = INT_MAX; int *item; for (i = 0, item = avl_t_last (&trav, tree); i < 2 * n && item != NULL; i++, item = avl_t_prev (&trav)) { if (*item >= next) { printf (" Tree out of order: %d precedes %d in traversal\n", *item, next); okay = 0; } next = *item; } if (i != n) { printf (" Tree should have %lu items, but has %lu in reverse\n", (unsigned long) n, (unsigned long) i); okay = 0; } } if (okay) { /* Check that |avl_t_init()| works properly. */ struct avl_traverser init, first, last; int *cur, *prev, *next; avl_t_init (&init, tree); avl_t_first (&first, tree); avl_t_last (&last, tree); cur = avl_t_cur (&init); if (cur != NULL) { printf (" Inited traverser should be null, but is actually %d.\n", *cur); okay = 0; } next = avl_t_next (&init); if (next != avl_t_cur (&first)) { printf (" Next after null should be %d, but is actually %d.\n", *(int *) avl_t_cur (&first), *next); okay = 0; } avl_t_prev (&init); prev = avl_t_prev (&init); if (prev != avl_t_cur (&last)) { printf (" Previous before null should be %d, but is actually %d.\n", *(int *) avl_t_cur (&last), *prev); okay = 0; } avl_t_next (&init); } return okay; }
Table_iterateur premier_iterateur_table( const Table* table ) { Table_iterateur it; avl_t_first( &it, table->root ); return it; }
uint32 blman_write_record(blman *self, uint64 recordkey, const uint8 *record, uint16 recordsize) { //size check if(recordsize > MAX_RECORD_SIZE) { return eBMS_FailRecordTooBig; } //variables uint32 retStatus = eBMS_Ok; uint8 rCompressedRecord[BLOCK_SIZE]; //PHASE 0 --> compression //try to compress if(recordsize > g_cfg.RecordSizeForCompression) { size_t outSize; int cStatus = CCommon_compressGzip_Buffer(g_cfg.GzipCompressionLevel, record, recordsize, rCompressedRecord, sizeof(rCompressedRecord), &outSize); if(cStatus == Z_OK && outSize < recordsize) { //replace record ptr and set new record size record = rCompressedRecord; recordsize = (uint16)outSize; g_stats.NumOfRecordCompressions++; } else { Log_Warning(__FUNCTION__, "Compression generated bigger size. Source size: %u, new size: " I64FMTD, recordsize, outSize); } } //PHASE 1 --> try to update //try to update record first blidxnode rNodeSearch = { recordkey, 0 }; blidxnode *pNodeFind = avl_find(self->blockIndex, &rNodeSearch); if(pNodeFind != NULL) { uint8 *block = blman_get_block(self, pNodeFind->m_blockNumber); //update E_BLS updateStatus = Block_UpdateRecord(block, recordkey, record, recordsize); if(updateStatus == eBLS_OK) { return retStatus; } //delete key, record will be on another block avl_delete(self->blockIndex, pNodeFind); blidxnode_destroy(pNodeFind, self->blockIndex->avl_param); } //PHASE 2 --> check record limit //block limit - start to rewrite from begin (record key is timestamp) if(g_cfg.EnableRecordLimit && self->blockIndex->avl_count >= g_cfg.RecordLimit) { int removedRecords = 0; //limit can be lowed so delete all records while(self->blockIndex->avl_count >= g_cfg.RecordLimit) { struct avl_traverser rTraverser; avl_t_init(&rTraverser, self->blockIndex); //delete 1st one (the oldest) blidxnode *node = avl_t_first(&rTraverser, self->blockIndex); if(node != NULL) { //DO NOT ADD OLDER DATA //check if new data are not the older one if(recordkey < node->m_key) { retStatus |= (eBMS_RecordCountLimit | eBMS_OldRecord); return retStatus; } //update counter ++removedRecords; //remove record from block blman_delete_record_by_node(self, node); //set return status retStatus |= eBMS_RecordCountLimit; } } //request defragment if(removedRecords >= g_cfg.DefragAfterRecordDelete) { retStatus |= eBMS_NeedDefrag; } } //PHASE 3 --> try to write //find empty space in blocks //search from end to begin -> mostly there appends to the end uint16 blockNum = self->blockCount; for(;;) { --blockNum; //get block and try to write uint8 *block = blman_get_block(self, blockNum); // E_BLS writeStatus = Block_WriteRecord(block, recordkey, record, recordsize); if(writeStatus == eBLS_OK) { blidxnode *node = blidxnode_create(recordkey, blockNum); avl_insert(self->blockIndex, node); break; } else if(blockNum == 0 && writeStatus == eBLS_NO_SPACE_FOR_NEW_DATA) { //realloc blocks + 1 -> modify m_blockCount blman_realloc_blocks(self); //set status retStatus |= eBMS_ReallocatedBlocks; //reset control variable blockNum = self->blockCount; } } return retStatus; }