Пример #1
0
void sl_add_index(Skiplist *sl,
		  SkiplistComparator comp,
		  SkiplistComparator compk) {
  struct skiplistnode *m;
  Skiplist *ni;
  int icount=0;
  Alarm(SKIPLIST, "Adding index to %p\n", sl);
  sl_find(sl->index, (void *)comp, &m);
  if(m) return; /* Index already there! */
  ni = (Skiplist *)malloc(sizeof(Skiplist));
  sli_init(ni);
  sl_set_compare(ni, comp, compk);
  /* Build the new index... This can be expensive! */
  m = sl_insert(sl->index, ni);
  while(m->prev) m=m->prev, icount++;
  for(m=sl_getlist(sl); m; sl_next(sl, &m)) {
    int j=icount-1;
    struct skiplistnode *nsln;
    nsln = sl_insert(ni, m->data);
    /* skip from main index down list */
    while(j>0) m=m->nextindex, j--;
    /* insert this node in the indexlist after m */
    nsln->nextindex = m->nextindex;
    if(m->nextindex) m->nextindex->previndex = nsln;
    nsln->previndex = m;
    m->nextindex = nsln;
  } 
}
Пример #2
0
static char *sl_test_update(void) {
    int v1 = 5;
    int v2 = 6;
    int *v;
    sl *slist = sl_create();

    sl_insert(slist, 9, &v1);
    sl_insert(slist, 9, &v2);

    v = sl_find(slist, 9);
    mu_assert("updating list with one element fails", *v == v2);
    sl_destroy(slist);
    return 0;
}
Пример #3
0
int main()
{
	srand((int)time(NULL)); 
	skiplist* S = (skiplist*)malloc(sizeof(skiplist));
	node nodes[2] = {
		{-1, &nodes[1], NULL},
		{1000000, NULL, NULL}
	};
	S->top = &nodes[0];

	int i;
	printf("Start...\n");
	scanf("%d", &i);
	while (i != -1) {
		if (i == -2) {
			sl_print(S);
		} else {
			sl_insert(S, i);
		}
		scanf("%d", &i);
	}
	delete(S);
	printf("End of program!\n");
	return 0;
}
Пример #4
0
vio_err_t vio_partition_val(vio_ctx *ctx, vio_val *v, vio_val *q, vio_val **out_rets, vio_val **out_parts) {
    vio_err_t err = 0;
    struct partition *p = NULL;
    struct partition_item *it = NULL;
    vio_val *ret;
    sl_skiplist parts;

    sl_init(&parts, cmp_vals, ctx, NULL, NULL);

    for (uint32_t i = 0; i < v->vlen; ++i) {
        VIO__ERRIF(ctx->sp >= VIO_STACK_SIZE, VE_STACK_OVERFLOW);
        ctx->stack[ctx->sp++] = v->vv[i];
        vio_exec(ctx, q->bc);
        ret = ctx->stack[--ctx->sp];
        if (!sl_find(&parts, ret, &p)) {
            VIO__ERRIF((p = (struct partition *)malloc(sizeof(struct partition))) == NULL, VE_ALLOC_FAIL);
            p->last = NULL;
            p->size = 0;
            sl_insert(&parts, ret, p, NULL);
        }
        VIO__ERRIF((it = (struct partition_item *)malloc(sizeof(struct partition_item))) == NULL, VE_ALLOC_FAIL);
        it->next = p->last;
        it->v = v->vv[i];
        p->last = it;
        ++p->size;
    }

    VIO__CHECK(vio_vec(ctx, out_rets, sl_size(&parts), NULL));
    VIO__CHECK(vio_vec(ctx, out_parts, sl_size(&parts), NULL));
    struct part_data pd = { .i = 0, .rets = *out_rets, .parts = *out_parts, .ctx = ctx };
    sl_iter(&parts, fill_partitions_and_free, &pd);
    sl_free(&parts);
    return 0;

    error:
    sl_iter(&parts, gotta_free_em_all, NULL);
    sl_free(&parts);
    return err;
}

vio_err_t vio_partition(vio_ctx *ctx) {
    vio_err_t err = 0;
    vio_val *q, *vec, *rets, *parts;
    VIO__RAISEIF(ctx->sp < 2, VE_STACK_EMPTY,
                 "Partition context requires a quotation and vector, but the "
                 "stack doesnt't have enough values.");

    VIO__CHECK(vio_coerce(ctx, ctx->stack[--ctx->sp], &q, vv_quot));
    VIO__CHECK(vio_coerce(ctx, ctx->stack[--ctx->sp], &vec, vv_vec));
    VIO__CHECK(vio_partition_val(ctx, vec, q, &rets, &parts));
    ctx->stack[ctx->sp++] = rets;
    ctx->stack[ctx->sp++] = parts;
    return 0;

    error:
    return err;
}
Пример #5
0
struct skiplistnode *sl_append(Skiplist *sl, void *data) {
  int nh=1, ch, compared;
  struct skiplistnode *lastnode, *nodeago;
  if(sl->bottomend != sl->bottom) {
    compared=sl->compare(data, sl->bottomend->prev->data);
    /* If it doesn't belong at the end, then fail */
    if(compared<=0) return NULL;
  }
  if(sl->preheight) {
    while(nh < sl->preheight && get_b_rand()) nh++;
  } else {
    while(nh <= sl->height && get_b_rand()) nh++;
  }
  /* Now we have the new hieght at which we wish to insert our new node */
  /* Let us make sure that our tree is a least that tall (grow if necessary)*/
  lastnode = sl->bottomend;
  nodeago = NULL;

  if(!lastnode) return sl_insert(sl, data);

  for(;sl->height<nh;sl->height++) {
    assert(sl->top);
    sl->top->up =
      (struct skiplistnode *)malloc(sizeof(struct skiplistnode));
    sl->top->up->down = sl->top;
    sl->top = sl->topend = sl->top->up;
    sl->top->prev = sl->top->next = sl->top->nextindex =
      sl->top->previndex = NULL;
    sl->top->data = NULL;
    sl->top->sl = sl;
  }
  ch = sl->height;
  while(nh) {
    struct skiplistnode *anode;
    anode =
      (struct skiplistnode *)malloc(sizeof(struct skiplistnode));
    anode->next = lastnode;
    anode->prev = lastnode->prev;
    anode->up = NULL;
    anode->down = nodeago;
    /* If this the bottom, we are appending, so bottomend should change */
    if(!nodeago) sl->bottomend = anode;
    if(lastnode->prev) {
      if(lastnode == sl->bottom)
	sl->bottom = anode;
      else if (lastnode == sl->top)
	sl->top = anode;
    }
    nodeago = anode;
    lastnode = lastnode->up;
    nh--;
  }
  sl->size++;
  return(nodeago);
}
Пример #6
0
/* Apply a merge of the two sorted lists */
struct sl* sl_join(struct sl *l1, struct sl *l2) {
	struct sl *joined = sl_init();
	sl_cursor cur1 = l1->lists[0].head->next;
	sl_cursor cur2 = l2->lists[0].head->next;
	while(cur1->next && cur2->next) {
		if(G_DATA_GREATER(cur1->data, cur2->data)) {
			sl_insert(joined, cur1->data);
			cur1 = cur1->next;
		} else {
			sl_insert(joined, cur2->data);
			cur2 = cur2->next;
		}
	}
	while(cur1->next) {
		sl_insert(joined, cur1->data);
		cur1 = cur1->next;
	}
	while(cur2->next) {
		sl_insert(joined, cur2->data);
		cur2 = cur2->next;
	}
	return joined;
}
Пример #7
0
void test_sl_join(CuTest* tc) {
    char* s1;
    sl* s = sl_new(4);
    sl_append(s, "123");
    sl_appendf(s, "%1$s%1$s", "testing");
    addsome(s, "%i", 456);
    sl_insert(s, 1, "inserted");
    sl_insertf(s, 2, "%s%s", "ins", "ertedf");
    s1 = sl_join(s, "");
    CuAssertStrEquals(tc, "123insertedinsertedftestingtesting456", s1);
    free(s1);
    s1 = sl_join(s, "--");
    CuAssertStrEquals(tc, "123--inserted--insertedf--testingtesting--456", s1);
    free(s1);
    s1 = sl_join_reverse(s, "--");
    CuAssertStrEquals(tc, "456--testingtesting--insertedf--inserted--123", s1);
    free(s1);

    sl_free2(s);
}
Пример #8
0
void test_setup(void) {
    srand(time(NULL));

    slist = sl_create();
    klist = kl_create();
    
    for(int i = 0; i < ARRAY_LEN(keys); i++) {
        sl_insert(slist, keys[i], &vals[i]);
    }
    sl_output(slist);

    printf("\n");

    for(int i = 0; i < ARRAY_LEN(keys); i++) {
        kl_insert(klist, keys[i], &vals[i]);
    }
    kl_output(klist);

    printf("\n");
}
Пример #9
0
static LocatorNode_t *locator_new_node (LocatorKind_t       kind,
					const unsigned char *addr,
			    		uint32_t            port)
{
	LocSearchData	data;
	LocatorNode_t	**npp, *np;
	int		is_new;

	data.kind = kind;
	data.addr = addr;
	data.port = port;

	npp = sl_insert (&loc_list, &data, &is_new, loc_cmp);
	if (!npp) {
		warn_printf ("locator_new_node: not enough memory for node!");
		return (NULL);
	}	
	if (is_new) {
		np = mds_pool_alloc (&mem_blocks [MB_LOCATOR]);
		if (!np) {
			warn_printf ("locator_new_node: not enough memory for locator data!");
#ifdef LIST_DELETE_NODE
			sl_delete_node (&loc_list, npp);
#else
			sl_delete (&loc_list, &data, loc_cmp);
#endif
			return (NULL);
		}
		np->users = 1;
		np->locator.kind = kind;
		np->locator.port = port;
		memcpy (np->locator.address, addr, sizeof (np->locator.address));
		memset (&np->locator.scope_id, 0, 8);
		*npp = np;
	}
	else {
		np = *npp;
		np->users++;
	}
	return (np);
}
Пример #10
0
Skiplist *sl_concat(Skiplist *sl1, Skiplist *sl2) {
  /* Check integrity! */
  Skiplist temp;
  struct skiplistnode *b2;
  if(sl1->bottomend == NULL || sl1->bottomend->prev == NULL) {
    sl_remove_all(sl1, free);
    temp = *sl1;
    *sl1 = *sl2;
    *sl2 = temp;
    /* swap them so that sl2 can be freed normally upon return. */
    return sl1;
  }
  if(sl2->bottom == NULL || sl2->bottom->next == NULL) {
    sl_remove_all(sl2, free);
    return sl1;
  }
  b2 = sl_getlist(sl2);
  while(b2) {
    sl_insert(sl1, b2->data);
    sl_next(sl2, &b2);
  }
  sl_remove_all(sl2, NULL);
  return sl1;
}
Пример #11
0
struct skiplistnode *sl_append(Skiplist *sl, void *data) {
  return sl_insert(sl, data);
}
Пример #12
0
struct skiplistnode *sl_insert_compare(Skiplist *sl,
				       void *data,
				       SkiplistComparator comp) {
  struct skiplistnode *m, *p, *tmp, *ret, **stack;
  int nh=1, ch, stacki;
  ret = NULL;
/*sl_print_struct(sl, "BI: ");*/
  if(!sl->top) {
    sl->height = 1;
    sl->topend = sl->bottomend = sl->top = sl->bottom = 
      (struct skiplistnode *)malloc(sizeof(struct skiplistnode));
    assert(sl->top);
    sl->top->next = sl->top->data = sl->top->prev =
	sl->top->up = sl->top->down = 
	sl->top->nextindex = sl->top->previndex = NULL;
    sl->top->sl = sl;
  }
  if(sl->preheight) {
    while(nh < sl->preheight && get_b_rand()) nh++;
  } else {
    while(nh <= sl->height && get_b_rand()) nh++;
  }
  /* Now we have the new height at which we wish to insert our new node */
  /* Let us make sure that our tree is a least that tall (grow if necessary)*/
  for(;sl->height<nh;sl->height++) {
    sl->top->up =
      (struct skiplistnode *)malloc(sizeof(struct skiplistnode));
    assert(sl->top->up);
    sl->top->up->down = sl->top;
    sl->top = sl->topend = sl->top->up;
    sl->top->prev = sl->top->next = sl->top->nextindex =
      sl->top->previndex = sl->top->up = NULL;
    sl->top->data = NULL;
    sl->top->sl = sl;
  }
  ch = sl->height;
  /* Find the node (or node after which we would insert) */
  /* Keep a stack to pop back through for insertion */
  m = sl->top;
  stack = (struct skiplistnode **)malloc(sizeof(struct skiplistnode *)*(nh));
  stacki=0;
  while(m) {
    int compared=-1;
    if(m->next) compared=comp(data, m->next->data);
    if(compared == 0) {
      free(stack);
      return 0;
    }
    if((m->next == NULL) || (compared<0)) {
            /* FIXME: This if ch<=nh test looks unnecessary. ch==nh at beginning of while(m)
             */
      if(ch<=nh) {
	/* push on stack */
	stack[stacki++] = m;
      }
      m = m->down;
      ch--;
    } else {
      m = m->next;
    }
  }
  /* Pop the stack and insert nodes */
  p = tmp = NULL;
  for(;stacki>0;stacki--) {
    m = stack[stacki-1];
    tmp = (struct skiplistnode *)malloc(sizeof(struct skiplistnode));
    tmp->next = m->next;
    if(m->next) m->next->prev=tmp;
    tmp->prev = m;
    tmp->up = NULL;
    tmp->nextindex = tmp->previndex = NULL;
    tmp->down = p;
    if(p) p->up=tmp;
    tmp->data = data;
    tmp->sl = sl;
    m->next = tmp;
    /* This sets ret to the bottom-most node we are inserting */
    if(!p) 
    {
            ret=tmp;
            sl->size++;
    }
    p = tmp;
  }
  free(stack);
  if(tmp && (tmp->prev == sl->topend)) {
    /* The last element on the top row is the new inserted one */
    sl->topend = tmp;
  }
  if(ret && (ret->prev == sl->bottomend)) {
    /* The last element on the bottom row is the new inserted one */
    sl->bottomend = ret;
  }
  if(sl->index != NULL) {
    /* this is a external insertion, we must insert into each index as well */
    struct skiplistnode *p, *ni, *li;
    li=ret;
    for(p = sl_getlist(sl->index); p; sl_next(sl->index, &p)) {
      ni = sl_insert((Skiplist *)p->data, ret->data);
      assert(ni);
      Alarm(SKIPLIST, "Adding %p to index %p\n", ret->data, p->data);
      li->nextindex = ni;
      ni->previndex = li;
      li = ni;
    }
  } 
  /* JRS: move size increment above to where node is inserted
    else {
    sl->size++;
  }
  */
/*sl_print_struct(sl, "AI: ");*/
  return ret;
}
Пример #13
0
int main( int argc, char **argv )
{
   sl_List       sl;
   int           count;
   int           i;

   maa_init( argv[0] );
   
   if (argc == 1) {
      count = 10;
   } else if (argc != 2 ) {
      fprintf( stderr, "usage: sltest count\n" );
      return 1;
   } else {
      count = atoi( argv[1] );
   }

   printf( "Running test for count of %d\n", count );

   sl = sl_create( compare, key, NULL );
   
   for (i = 1; i < count; i++) {
      printf( "adding %d\n", i );
      sl_insert( sl, (void *) (intptr_t) i );
#ifdef DUMP
      _sl_dump( sl );
#endif
   }

   sl_iterate( sl, print );
   printf( "\n" );

   sl_delete( sl, (void *)5 );
   sl_iterate( sl, print );
   printf( "\n" );

   sl_insert( sl, (void *)0 );
   sl_iterate( sl, print );
   printf( "\n" );
   sl_insert( sl, (void *)66 );
   sl_iterate( sl, print );
   printf( "\n" );
   sl_insert( sl, (void *)100 );
   sl_iterate( sl, print );
   printf( "\n" );
   sl_insert( sl, (void *)-1 );
   sl_iterate( sl, print );
   printf( "\n" );
   sl_insert( sl, (void *)5 );
   sl_iterate( sl, print );
   printf( "\n" );
   sl_insert( sl, (void *)67 );
   sl_iterate( sl, print );
   printf( "\n" );
   sl_insert( sl, (void *)68 );
   sl_iterate( sl,print );
   printf( "\n" );
   sl_insert( sl, (void *)65 );
   sl_iterate( sl, print );
   printf( "\n" );
   
   sl_destroy( sl );

   return 0;
}
Пример #14
0
LocatorNode_t *locator_list_add (LocatorList_t       *list,
				 LocatorKind_t       kind,
				 const unsigned char *addr,
				 uint32_t            port,
				 uint32_t            scope_id,
				 Scope_t             scope,
				 unsigned            flags,
				 unsigned            sproto)
{
	LocSearchData	data;
	LocatorNode_t	**npp, *np;
	LocatorRef_t	*rp, *p;
	int		is_new;

	data.kind = kind;
	data.addr = addr;
	data.port = port;

	lock_take (loc_lock);
	npp = sl_insert (&loc_list, &data, &is_new, loc_cmp);
	if (!npp) {
		warn_printf ("locator_list_add: not enough memory for list node!");
		lock_release (loc_lock);
		return (NULL);
	}
	if (is_new) {
		np = mds_pool_alloc (&mem_blocks [MB_LOCATOR]);
		if (!np) {
			warn_printf ("locator_list_add: not enough memory for locator node!");
#ifdef LIST_DELETE_NODE
			sl_delete_node (&loc_list, npp);
#else
			sl_delete (&loc_list, &data, loc_cmp);
#endif
			lock_release (loc_lock);
			return (NULL);
		}
		np->users = 0;
		np->locator.kind = kind;
		np->locator.port = port;
		memcpy (np->locator.address, addr, sizeof (np->locator.address));
		np->locator.scope_id = scope_id;
		np->locator.scope = scope;
		np->locator.flags = flags;
		np->locator.sproto = sproto;
		np->locator.intf = 0;
		np->locator.handle = 0;
		*npp = np;
	}
	else {
		np = *npp;
		if (np->locator.scope_id != scope_id ||
		    (np->locator.scope && scope && np->locator.scope != scope) ||
		    /*(np->locator.flags && flags && 
		     (np->locator.flags & LOCF_MFLAGS) != (flags & LOCF_MFLAGS)) ||*/
		    (np->locator.sproto && sproto && np->locator.sproto != sproto))
			log_printf (LOC_ID, 0, "locator_list_add: incompatible locator attributes for %s, "
						"%u:%u, %u:%u, 0x%x:0x%x, %u:%u!\r\n",
					locator_str (&np->locator),
					np->locator.scope_id, scope_id,
					np->locator.scope, scope,
					np->locator.flags, flags,
					np->locator.sproto, sproto);

		if (!np->locator.scope_id && scope_id)
			np->locator.scope_id = scope_id;
		if (!np->locator.scope && scope)
			np->locator.scope = scope;
		if (flags && np->locator.flags != flags)
			np->locator.flags |= flags;
		if (!np->locator.sproto && sproto)
			np->locator.sproto = sproto;

		/* Check if already in list. */
		for (rp = *list; rp; rp = rp->next)
			if (rp->data == np) {	/* Already there! */
				lock_release (loc_lock);
				return (0);
			}
	}
#ifdef LOG_LOCATORS
	log_printf (LOC_ID, 0, "LOC: locator_list_add (list=%p, %s)\r\n", (void *) list, locator_str (&np->locator));
#endif
	rp = mds_pool_alloc (&mem_blocks [MB_LOCREF]);
	if (!rp) {
		warn_printf ("locator_list_add: not enough memory for locator reference!\r\n");
		if (is_new) {
			mds_pool_free (&mem_blocks [MB_LOCATOR], np);
#ifdef LIST_DELETE_NODE
			sl_delete_node (&loc_list, npp);
#else
			sl_delete (&loc_list, &data, loc_cmp);
#endif
		}
		lock_release (loc_lock);
		return (NULL);
	}
	rp->next = NULL;
	rp->data = np;
	np->users++;
 	lock_release (loc_lock);
	if (*list) {
		for (p = *list; p->next; p = p->next)
			;
		p->next = rp;
	}
	else
		*list = rp;
	return (np);
}
Пример #15
0
static char *test_speed_compare(void) {
    struct _timeb start;
    struct _timeb finish;
    unsigned long sl_time_taken;
    unsigned long kl_time_taken;
    int keys[10000];
    int vals[10000];
    int test_keys[100];
    sl *slist = sl_create();
    kl *klist = kl_create();
    int *v;

    _ftime(&start);
    /* generate long list (same for both) */
    for(int i = 0; i < 10000; i++) {
        keys[i] = rand();
        vals[i] = rand();
    }
    for(int i = 0; i < 100; i++) {
        test_keys[i] = rand() % 10000;
    }

    /* fill lists with it (time this) */
    _ftime(&start);
    for(int i = 0; i < 10000; i++) {
        kl_insert(klist, keys[i], &vals[i]);
    }
    _ftime(&finish);
    printf("kl: inserted 10,000 keys in %lums\n", ftime_diff(&start, &finish));

    _ftime(&start);
    for(int i = 0; i < 10000; i++) {
        sl_insert(slist, keys[i], &vals[i]);
    }
    _ftime(&finish);
    printf("sl: inserted 10,000 keys in %lums\n", ftime_diff(&start, &finish));

    /* find random values in it (same for both) n times, average time taken */
    _ftime(&start);
    for(int i = 0; i < 1000; i++) {
        for(int j = 0; j < 100; j++) {
            v = sl_find(slist, keys[test_keys[j]]);
        }
    }
    _ftime(&finish);
    sl_time_taken = ftime_diff(&start, &finish);

    _ftime(&start);
    for(int i = 0; i < 1000; i++) {
        for(int j = 0; j < 100; j++) {
            v = kl_find(klist, keys[test_keys[j]]);
        }
    }
    _ftime(&finish);
    kl_time_taken = ftime_diff(&start, &finish);

    printf("sl: found 100,000 keys in %fs, %.2fkeys/s\n", sl_time_taken/1000.0, 100.0*100000/sl_time_taken);
    printf("kl: found 100,000 keys in %fs, %.2fkeys/s\n\n", kl_time_taken/1000.0, 100.0*100000/kl_time_taken);

    mu_assert("average sl find speed is slower than kl", sl_time_taken < kl_time_taken);

    sl_destroy(slist);
    kl_destroy(klist);

    return 0;
}