/*
 * libsal/skiplists/insert.c
 * Insert a new key into the skip lists
 * 
 * See libsal/license.h for copyright details
 */

#include <libsal/skiplists/internal.h>
#include <libsal/license.h>
#include <libsal/proto.h>
#include <libsal/defines.h>
#include <libsal/types.h>

int sal_skiplist_Insert (sal_skiplist_skiplist pstList, void *szValue)
{
  int k;
  sal_skiplist_node update[SAL_SKIPLIST_MAXNOOFLEVELS];
  sal_skiplist_node p, q;
  
  assert(pstList != NULL);
  assert(szValue != NULL);
  
  q = sal_skiplist_FindForUpdate(pstList, szValue, update);
  
  if ((*pstList->compare_func)(q->szData, szValue) != 0)
    return 0;
  
  k = sal_skiplist_GetRandomLevel();
  if (k > pstList->iLevel)
  {
    k = ++pstList->iLevel;
    update[k] = pstList->pstHeader;
  }
  
  q = sal_skiplist_NewNodeOfLevel(k);
  q->szData = szValue;
  
  do
  {
    p = update[k];
    q->pstForward[k] = p->pstForward[k];
    p->pstForward[k] = q;
  } while (--k > 0);
  
  return 1;
}
