Exemple #1
0
void SkipList::insert(const Key searchKey, const Value value)
{
  int i;
  long newLevel;
  SkipListElement* element;
  SkipListElement* nextElement;
  SkipListElement  update(SKIPLIST_MAXLEVEL);

  // scan all levels while key < searchKey
  // starting with header in his level
  element = myHeader;
  for(i=myHeader->getLevel(); i>=0; i--) {
    nextElement = element->getElement(i);
    while( (nextElement != NIL) && (nextElement->getKey() < searchKey) ) {
      element=nextElement;
      nextElement = element->getElement(i);
    }
    update.setElement(i, element); // save level pointer
  }

  element=element->getElement(0); // key is < searchKey

  // key exists. set new value
  //
  if( (element != NIL) && (element->getKey() == searchKey) ) {
    //    cerr << "(dup " << searchKey << ")"; // print # to cout. remove later!
    element->setValue(value);
  }  else {			// new key. add to list
    // get new level and fix list level
    newLevel = getNewLevel(SKIPLIST_MAXLEVEL, myProbability); // get new level
    if (newLevel > myHeader->getLevel() ) { // adjust header level
      for (i=myHeader->getLevel() + 1; i<=newLevel; i++) {
	update.setElement(i, myHeader); // adjust new pointer of new element
      }
      myHeader->setLevel(newLevel); // set new header level
    }
    // make new element [NEW *******]
    myLength++;
    element = new SkipListElement(newLevel, searchKey, value);
    for (i=0; i<= newLevel; i++ ) { // scan all levels
      // set next pointer of new element
      element->setElement(i, update.getElement(i)->getElement(i));
     update.getElement(i)->setElement(i, element);
    }
    
    /*
    // fix level of element -- why not?
    if(newLevel < update.getLevel()) {
      update.setLevel(newLevel);
    }
    */
  }
}
Exemple #2
0
/***************************************************************************
 * Function    : SkipListFindOrInsert()
 * Description : Searches for the specified data item
 *               If found returns it, otherwise allocates one using
 *                 user specified function, sets key and data and then
 *                 returns it. 
 *               If no user specified function exists, the given key
 *               and data are inserted.
 *              
 *
 * Input       : The list in which the element is to be inserted, key,
 *               element to be inserted, a allocation function if new key and
 *               data are to be allocated, a return value for a flag to indicate
 *               if allocation was called.
 * Output      : sets found if it found an element.
 * Returns     : Node ptr on success, NULL on failiure
 * ***************************************************************************/
SkipListNode_t *
SkipListFindOrInsert( SkipList_t *list, void *key, void *value , SkipListUserAlloc_t allocFn, int *found )
{
    int i = 0;
    int newLevel = 0;
    SkipListNode_t *x= NULL;
    SkipListNode_t *update[SKIPLIST_MAXLEVEL];
    void *newKey;
    void *newValue;
    
    *found = 0;
    
    /*
     * Scan all levels while (list-key<serach-key) starting
     * with header in its level. 
     */
    for ( x=list->header, i=list->level; i >= 0; i-- ) {
        while ( x->forward[i] != 0 &&
                list->cmpFn(x->forward[i]->key, key) < 0 ) {
            x = x->forward[i];
        }
        /*
         * Save level pointer. 
         */
        update[i] = x;
    }
    x = x->forward[0];
    /*
     * Element already exists. 
     */

    if ( x && list->cmpFn(x->key, key) == 0 ) {

        *found = 1;

        return x;

    }


    /*
     * Put a new element in the list for this key.
     * Get the new level and fix the list level.
     */

    newLevel = getNewLevel( list->maxLevels );
    /*
     * Adjust the header level. 
     */
    if ( newLevel > list->level ) {
        for ( i=list->level+1; i<=newLevel; i++ ) {
            update[i] = list->header;
        }
        list->level = newLevel;
    }

    if ( allocFn ) {

        /*
         * User has a callback function to allocate newKey and newValue
         */

        if ( !allocFn(key,value,&newKey,&newValue) )
            return NULL;

    } else {

        /*
         * User intends to insert the supplied key and value
         */

        newKey = key;

        newValue = value;

    }

    /*
     * Make the new element and insert it in the list. 
     */
    x = newSkipListNode( list, newKey, newValue, newLevel );

    if (!x)
        return NULL;

    /*
     * Scan all levels.
     */
    for ( i=0; i<=newLevel; i++ ) {
        /*
         * Set the next pointer of the new element. 
         */
        x->forward[i] = update[i]->forward[i];
        update[i]->forward[i] = x;
    }
    list->numNodes++;
    
    return x;

}
Exemple #3
0
/***************************************************************************
 * Function    : SkipListInstert()
 * Description : Inserts the given element in the skip list at
 *               the right place based on the specified key. 
 * Input       : The list in which the element is to be inserted, key,
 *               element to be inserted and a flag which indicates
 *               whether to replace the existing element, if any. 
 * Output      : None.
 * Returns     : 0 -- success, -1 -- failure
 * ***************************************************************************/
int
SkipListInsert( SkipList_t *list, void *key, void *value, int replace ) 
{
    int i = 0;
    int newLevel = 0;
    SkipListNode_t *x= NULL;
    SkipListNode_t *update[SKIPLIST_MAXLEVEL];
    
    /*
     * Scan all levels while (list-key<serach-key) starting
     * with header in its level. 
     */
    for ( x=list->header, i=list->level; i >= 0; i-- ) {
        while ( x->forward[i] != 0 &&
                list->cmpFn(x->forward[i]->key, key) < 0 ) {
            x = x->forward[i];
        }
        /*
         * Save level pointer. 
         */
        update[i] = x;
    }
    x = x->forward[0];
    /*
     * Element already exists. 
     */
    if ( x && list->cmpFn(x->key, key) == 0 ) {
        if ( replace ) {
            list->freeFn( x->value );
            x->key = key;
            x->value = value;
            return( 0 );
        }
        else
            return( -1 );
    }
    /*
     * Put a new element in the list for this key.
     * Get the new level and fix the list level.
     */
    newLevel = getNewLevel( list->maxLevels );
    /*
     * Adjust the header level. 
     */
    if ( newLevel > list->level ) {
        for ( i=list->level+1; i<=newLevel; i++ ) {
            update[i] = list->header;
        }
        list->level = newLevel;
    }
    /*
     * Make the new element and insert it in the list. 
     */
    x = newSkipListNode( list, key, value, newLevel );
    /*
     * Scan all levels.
     */
    for ( i=0; i<=newLevel; i++ ) {
        /*
         * Set the next pointer of the new element. 
         */
        x->forward[i] = update[i]->forward[i];
        update[i]->forward[i] = x;
    }
    list->numNodes++;
    
    return(0);
}