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); } */ } }
/*************************************************************************** * 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; }
/*************************************************************************** * 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); }