Beispiel #1
0
// smallest greater than searchKey.. almost completely, but not
// quite entirely unlike a search ...
Key SkipList::findMIN(const Key searchKey) const
{
    int i;
    SkipListElement* element(myHeader);
    SkipListElement* nextElement = 0;
    Key retKey;

    for(i=myHeader->getLevel(); i>=0; i--) {
        nextElement = element->getElement(i);
        while( (nextElement != NIL) && (nextElement->getKey() <= searchKey) ) {
            element=nextElement;
            nextElement = element->getElement(i);
        }
    }
    // now nextElement is > searchKey
    // element is <= , make it >
    //
    element = nextElement;
    if(element != NIL) {
        retKey = element->getKey();
        return retKey == KEY_MAX ? (-KEY_MAX) : retKey;
    } else {
        return (Key)KEY_MAX;
    }
}
Beispiel #2
0
void SkipList::freeRange(const Key loKey, const Key hiKey)
{
  /* Very similar to free, but frees a range of keys
     from lo to hi, inclusive */

  int i;
  SkipListElement* element;
  SkipListElement* nextElement;


  // scan all levels while key < searchKey
  // starting with header in his level
  //
  //  cerr << "freeRange from " << loKey << " to " << hiKey << endl;
  element = myHeader;
  for(i=myHeader->getLevel(); i>=0; i--) {
    nextElement = element->getElement(i);
    while( (nextElement != NIL) && (nextElement->getKey() < loKey) ) {
      element=nextElement;
      nextElement = element->getElement(i);
    }
  }

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

  // [ed:diff] while keys exists

  //  cerr << "freeRange begins deleting at  " << element->getKey() << endl;
  while( (element != NIL) && (element->getKey() <= hiKey) ) {
    //    cerr << "freeRange wants to delete " << element->getKey() << endl;
    nextElement = element->getElement(0);
    free(element->getKey());
    element = nextElement;
  }
}
Beispiel #3
0
/* Very similar to free, but frees a range of keys
   from lo to hi, inclusive */
void SkipList::freeRange(const Key loKey, const Key hiKey)
{
    int i;
    SkipListElement* element;
    SkipListElement* nextElement;

    // 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() < loKey) ) {
            element=nextElement;
            nextElement = element->getElement(i);
        }
    }
    // key is < loKey
    element=element->getElement(0);

    while( (element != NIL) && (element->getKey() <= hiKey) ) {
        nextElement = element->getElement(0);
        free(element->getKey());
        element = nextElement;
    }
}
Beispiel #4
0
Value SkipList::search(const Key searchKey, int iterator_flag)
{
  int i;
  SkipListElement* element;
  SkipListElement* nextElement;

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

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

  // if key exists return value else ERROR
  if( (element != NIL) && (element->getKey() == searchKey) ) {
    if (iterator_flag > 0){
      iter = element;
    }
    return(element->getValue());
  }
  else
    return(SKIPLIST_NOT_FOUND);
}
  bool find(const Tval& value)
  {
    // Just a helper metric, to see how fast we are.
    this->find_steps = 0;
    this->find_value = value;

    // We have to empty the last_visited map for each run of find.
    this->last_visited.clear();
    SkipListElement<Tval>* head = this->get_first_element();

    // Initial check to see whether value must be appended to front
    if (!head || this->first_elements[0]->value > value)
      return false;

   // head is smaller/equal to value -> visit
   this->last_visited[this->max_level] = head;
   ++(this->find_steps);

   // head is valid
   for (int level = this->max_level; level > -1; --level)
   {
     // The first entry in the list[level+1] only contained bigger elements,
     // restart at first element of list[level]
     if (head->value > value)
     {
       // This begs the question on how to reset last_visited for level+1
       // when we overshot (or even better, prevent overshooting!).
       // The bug becomes visible quickly once we start to look at greater
       // sequences (unordered lists for level > 0).
       // It means that last_visited will sometimes be bigger than value, which
       // is a logical error. The effect is that we effectivly truncat the
       // level+1 list upon insertion, thus making find() very costly (as in O(n)).
       head = this->first_elements[level];
     }

     this->last_visited[level] = head;

     while (head->value <= value)
     {
       this->last_visited[level] = head;
       SkipListElement<Tval>* next = head->get_next_at(level);
       if (!next)
         break;
       head = next;
       ++(this->find_steps);
     }
   }
   return (this->last_visited[0]->value == value ||
           this->first_elements[0]->value == value);
  }
Beispiel #6
0
void SkipList::freeAll()
{
  /* Very similar to free, but frees all */

  SkipListElement* element;
  SkipListElement* nextElement;

  element = myHeader;
  element=element->getElement(0);
  while( (element != NIL)  ) {
    nextElement = element->getElement(0);
    free(element->getKey());
    element = nextElement;
  }
}
Beispiel #7
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);
    }
    */
  }
}
  void print()
  {
    std::cout
      << std::endl
      << "Skiplist contents (last find() run for "
      << this->find_value << " took "
      << this->find_steps << " steps): "
      << std::endl;

    for (int level = this->max_level; level > -1; --level)
    {
      std::cout << "level " << level << ":  ";
      SkipListElement<Tval>* head = this->first_elements[level];
      while(head)
      {
         std::cout << head->value << "  ";
         head = head->get_next_at(level);
      }
      std::cout << std::endl;
    }
  }
Beispiel #9
0
Key SkipList::findMIN(const Key searchKey) const
  // smallest greater than searchKey.. almost completely, but not
  // quite entirely unlike a search ...
{
  int i;
  SkipListElement* element;
  SkipListElement* nextElement;
  Key retKey;

  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);
    }
  }
  // now nextElement is > searhcKey
  // element is <= , make it >
  //
  element = nextElement;
  if(element != NIL) {
    retKey = element->getKey();
    return( retKey == KEY_MAX ? (-KEY_MAX) : retKey);
  }
  else
    return((Key) KEY_MAX);
}
Beispiel #10
0
Key SkipList::findMAX(const Key searchKey) const
  // greatest key less than searchKey.. almost completely, but not
  // quite entirely unlike a search ...
{
  int i;
  SkipListElement* element;
  SkipListElement* nextElement;
  Key retKey;

  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);
    }
  }
  // now nextElement is >= searhcKey
  // and element is < searchKey
  // therefore elemnt  key is largest key less than current

  // if this were search:
  // element=element->getElement(0); // skip to >= 

  
  if(element != NIL) {
    retKey = element->getKey();
    return( retKey == KEY_MAX ? (-KEY_MAX) : retKey);
  }
  else
    return((Key) KEY_MAX);
}
Beispiel #11
0
ostream& operator<<(ostream& os, const SkipList& list)
{
  int i;
  SkipListElement* element;

  // print header info
  element = list.myHeader;
  os << "Sl prob. = " << list.myProbability << endl;
  os << "Header " << setw(OS_DEFAULT_WIDTH) << "" << *element << endl;

  // print all levels
  //!!  for(i=SKIPLIST_MAXLEVEL - 1; i>=0; i--){
  for(i=list.myHeader->getLevel(); i>=0; i--){
    element = list.myHeader->getElement(i);
    if (element!=NIL) os << endl;
    while(element!=NIL) {
      // print element in level
      os << "(i" << setw(OS_DEFAULT_WIDTH) << i << " (elt " << *element << ")" << endl;
      element = element->getElement(i);
    }
  }
  return(os);
}
Beispiel #12
0
//// STATISTICS on skiplist
void SkipList::stat()
{
  int count = 0;
  SkipListElement* element;
  SkipListElement* nextElement;

  element = myHeader;
  nextElement = element->getElement(0);

  while( (nextElement != NIL) ) {
    count++;
    element=nextElement;
    nextElement = element->getElement(0);
  }
  cout << "Have number of elements ... " << count << endl;
  cout << "Size  ..................... " << myLength << endl;
  {
    int *hist;
    hist = new int[20];
	int i;
    long totalPointers, usedPointers;
    for(i=0; i<20; i++){
      hist[i] = 0;
    }
    element = myHeader;
    count = 0;
    nextElement = element->getElement(0);
    while( (nextElement != NIL) ) {
      count++;
      hist[nextElement->getLevel()]++;
      element=nextElement;
      nextElement = element->getElement(0);
    }
    // 
    // There are SKIPLIST_MAXLEVEL * count available pointers
    //
    totalPointers = SKIPLIST_MAXLEVEL * count;
    usedPointers = 0;
    //
    // of these every node that is not at the max level wastes some
    //
    for(i=0; i<20; i++){
      if(hist[i] > 0) cout << setw(2) << i << ": " << setw(6) << hist[i] << endl;
      usedPointers += hist[i] * (1 + i);
    }
    cout << "Used  pointers " << usedPointers << endl;
    cout << "Total pointers " << totalPointers << " efficiency = " << 
      (double) usedPointers / (double) totalPointers << endl;
    delete hist;
  }
  return;
}
Beispiel #13
0
void SkipList::free(const Key searchKey)
{
    int i;
    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);
        }
        // save level pointer
        update.setElement(i, element);
    }

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

    // if key exists
    if( (element != NIL) && (element->getKey() == searchKey) ) {
        for(i=0; i<=myHeader->getLevel(); i++) { // save next pointers
            if (update.getElement(i)->getElement(i) == element) {
                update.getElement(i)->setElement(i, element->getElement(i));
            }
        }

        // free memory of element
        delete element;
        myLength--;

        // set new header level
        while ( (myHeader->getLevel() > 0) && (myHeader->getElement(myHeader->getLevel()) == NIL) ) {
            myHeader->setLevel(myHeader->getLevel()-1);
        }
    }
}
Beispiel #14
0
//////////ITERATOR/////////////////////////////////////////////////////////////
// see the .h file
///////////////////////////////////////////////////////////////////////////////
void SkipList::list(ostream & os)
{
  os << "List ing start *****************************************" << endl;
  SkipListElement* element;
  SkipListElement* nextElement;

  element = myHeader;
  nextElement = element->getElement(0);
  while( (nextElement != NIL) ) {
    os << setw(20) << nextElement->getKey() << " " << setw(4) << nextElement->getValue() << " " <<  endl; 
    element=nextElement;
    nextElement = element->getElement(0);
  }
  os << "List end ***********************************************" << endl;
  return;
}