Beispiel #1
0
/* 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;
}
Beispiel #2
0
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
}
Beispiel #4
0
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);
   }   
}
Beispiel #5
0
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);
}
Beispiel #6
0
/*!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);
   }   
}
Beispiel #7
0
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);
   }
}
Beispiel #8
0
// 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);
}
Beispiel #9
0
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;
   }
}
Beispiel #10
0
void *stSortedSet_getFirst(stSortedSet *items) {
    struct avl_traverser traverser;
    avl_t_init(&traverser, items->sortedSet);
    return avl_t_first(&traverser, items->sortedSet);
}
Beispiel #11
0
/* 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;
}
Beispiel #13
0
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;
}