Пример #1
0
/* Checks that |tree| is well-formed
   and verifies that the values in |array[]| are actually in |tree|.
   There must be |n| elements in |array[]| and |tree|.
   Returns nonzero only if no errors detected. */
static int
verify_tree (struct tavl_table *tree, int array[], size_t n)
{
  int okay = 1;

  /* Check |tree|'s bst_count against that supplied. */
  if (tavl_count (tree) != n)
    {
      printf (" Tree count is %lu, but should be %lu.\n",
              (unsigned long) tavl_count (tree), (unsigned long) n);
      okay = 0;
    }

  if (okay)
    {
      /* Recursively verify tree structure. */
      size_t count;
      int height;

      recurse_verify_tree (tree->tavl_root, &okay, &count,
                           0, INT_MAX, &height);
      if (count != n)
        {
          printf (" Tree has %lu nodes, but should have %lu.\n",
                  (unsigned long) count, (unsigned long) n);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that all the values in |array[]| are in |tree|. */
      size_t i;

      for (i = 0; i < n; i++)
        if (tavl_find (tree, &array[i]) == NULL)
          {
            printf (" Tree does not contain expected value %d.\n", array[i]);
            okay = 0;
          }
    }

  if (okay)
    {
      /* Check that |tavl_t_first()| and |tavl_t_next()| work properly. */
      struct tavl_traverser trav;
      size_t i;
      int prev = -1;
      int *item;

      for (i = 0, item = tavl_t_first (&trav, tree); i < 2 * n && item != NULL;
           i++, item = tavl_t_next (&trav))
        {
          if (*item <= prev)
            {
              printf (" Tree out of order: %d follows %d in traversal\n",
                      *item, prev);
              okay = 0;
            }

          prev = *item;
        }

      if (i != n)
        {
          printf (" Tree should have %lu items, but has %lu in traversal\n",
                  (unsigned long) n, (unsigned long) i);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that |tavl_t_last()| and |tavl_t_prev()| work properly. */
      struct tavl_traverser trav;
      size_t i;
      int next = INT_MAX;
      int *item;

      for (i = 0, item = tavl_t_last (&trav, tree); i < 2 * n && item != NULL;
           i++, item = tavl_t_prev (&trav))
        {
          if (*item >= next)
            {
              printf (" Tree out of order: %d precedes %d in traversal\n",
                      *item, next);
              okay = 0;
            }

          next = *item;
        }

      if (i != n)
        {
          printf (" Tree should have %lu items, but has %lu in reverse\n",
                  (unsigned long) n, (unsigned long) i);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that |tavl_t_init()| works properly. */
      struct tavl_traverser init, first, last;
      int *cur, *prev, *next;

      tavl_t_init (&init, tree);
      tavl_t_first (&first, tree);
      tavl_t_last (&last, tree);

      cur = tavl_t_cur (&init);
      if (cur != NULL)
        {
          printf (" Inited traverser should be null, but is actually %d.\n",
                  *cur);
          okay = 0;
        }

      next = tavl_t_next (&init);
      if (next != tavl_t_cur (&first))
        {
          printf (" Next after null should be %d, but is actually %d.\n",
                  *(int *) tavl_t_cur (&first), *next);
          okay = 0;
        }
      tavl_t_prev (&init);

      prev = tavl_t_prev (&init);
      if (prev != tavl_t_cur (&last))
        {
          printf (" Previous before null should be %d, but is actually %d.\n",
                  *(int *) tavl_t_cur (&last), *prev);
          okay = 0;
        }
      tavl_t_next (&init);
    }

  return okay;
}
Пример #2
0
int
main( int argc, char **argv )
{
	Avlnode	*tree = NULL, *n;
	char	command[ 10 ];
	char	name[ 80 ];
	char	*p;

	printf( "> " );
	while ( fgets( command, sizeof( command ), stdin ) != NULL ) {
		switch( *command ) {
		case 'n':	/* new tree */
			( void ) tavl_free( tree, free );
			tree = NULL;
			break;
		case 'p':	/* print */
			( void ) myprint( tree );
			break;
		case 't':	/* traverse with first, next */
			printf( "***\n" );
			for ( n = tavl_end( tree, TAVL_DIR_LEFT );
			    n != NULL;
				n = tavl_next( n, TAVL_DIR_RIGHT ))
				printf( "%s\n", n->avl_data );
			printf( "***\n" );
			break;
		case 'f':	/* find */
			printf( "data? " );
			if ( fgets( name, sizeof( name ), stdin ) == NULL )
				exit( EXIT_SUCCESS );
			name[ strlen( name ) - 1 ] = '\0';
			if ( (p = (char *) tavl_find( tree, name, avl_strcmp ))
			    == NULL )
				printf( "Not found.\n\n" );
			else
				printf( "%s\n\n", p );
			break;
		case 'i':	/* insert */
			printf( "data? " );
			if ( fgets( name, sizeof( name ), stdin ) == NULL )
				exit( EXIT_SUCCESS );
			name[ strlen( name ) - 1 ] = '\0';
			if ( tavl_insert( &tree, strdup( name ), avl_strcmp,
			    avl_dup_error ) != 0 )
				printf( "\nNot inserted!\n" );
			break;
		case 'd':	/* delete */
			printf( "data? " );
			if ( fgets( name, sizeof( name ), stdin ) == NULL )
				exit( EXIT_SUCCESS );
			name[ strlen( name ) - 1 ] = '\0';
			if ( tavl_delete( &tree, name, avl_strcmp ) == NULL )
				printf( "\nNot found!\n" );
			break;
		case 'q':	/* quit */
			exit( EXIT_SUCCESS );
			break;
		case '\n':
			break;
		default:
			printf("Commands: insert, delete, print, new, quit\n");
		}

		printf( "> " );
	}

	return( 0 );
}
Пример #3
0
int mdb_tool_idl_add(
	MDB_cursor *mc,
	struct berval *keys,
	ID id )
{
	MDB_dbi dbi;
	mdb_tool_idl_cache *ic, itmp;
	mdb_tool_idl_cache_entry *ice;
	int i, rc, lcount;
	AttrInfo *ai = (AttrInfo *)mc;
	mc = ai->ai_cursor;

	dbi = ai->ai_dbi;
	for (i=0; keys[i].bv_val; i++) {
	itmp.kstr = keys[i];
	ic = tavl_find( (Avlnode *)ai->ai_root, &itmp, mdb_tool_idl_cmp );

	/* No entry yet, create one */
	if ( !ic ) {
		MDB_val key, data;
		ID nid;
		int rc;

		if ( ai->ai_clist ) {
			ic = ai->ai_clist;
			ai->ai_clist = ic->head;
		} else {
			ic = ch_malloc( sizeof( mdb_tool_idl_cache ) + itmp.kstr.bv_len + 4 );
		}
		ic->kstr.bv_len = itmp.kstr.bv_len;
		ic->kstr.bv_val = (char *)(ic+1);
		memcpy( ic->kstr.bv_val, itmp.kstr.bv_val, ic->kstr.bv_len );
		ic->head = ic->tail = NULL;
		ic->last = 0;
		ic->count = 0;
		ic->offset = 0;
		ic->flags = 0;
		tavl_insert( (Avlnode **)&ai->ai_root, ic, mdb_tool_idl_cmp,
			avl_dup_error );

		/* load existing key count here */
		key.mv_size = keys[i].bv_len;
		key.mv_data = keys[i].bv_val;
		rc = mdb_cursor_get( mc, &key, &data, MDB_SET );
		if ( rc == 0 ) {
			ic->flags |= WAS_FOUND;
			nid = *(ID *)data.mv_data;
			if ( nid == 0 ) {
				ic->count = MDB_IDL_DB_SIZE+1;
				ic->flags |= WAS_RANGE;
			} else {
				size_t count;

				mdb_cursor_count( mc, &count );
				ic->count = count;
				ic->first = nid;
				ic->offset = count & (IDBLOCK-1);
			}
		}
	}
	/* are we a range already? */
	if ( ic->count > MDB_IDL_DB_SIZE ) {
		ic->last = id;
		continue;
	/* Are we at the limit, and converting to a range? */
	} else if ( ic->count == MDB_IDL_DB_SIZE ) {
		if ( ic->head ) {
			ic->tail->next = ai->ai_flist;
			ai->ai_flist = ic->head;
		}
		ic->head = ic->tail = NULL;
		ic->last = id;
		ic->count++;
		continue;
	}
	/* No free block, create that too */
	lcount = ic->count & (IDBLOCK-1);
	if ( !ic->tail || lcount == 0) {
		if ( ai->ai_flist ) {
			ice = ai->ai_flist;
			ai->ai_flist = ice->next;
		} else {
			ice = ch_malloc( sizeof( mdb_tool_idl_cache_entry ));
		}
		ice->next = NULL;
		if ( !ic->head ) {
			ic->head = ice;
		} else {
			ic->tail->next = ice;
		}
		ic->tail = ice;
		if ( lcount )
			ice->ids[lcount-1] = 0;
		if ( !ic->count )
			ic->first = id;
	}
	ice = ic->tail;
	if (!lcount || ice->ids[lcount-1] != id)
		ice->ids[lcount] = id;
	ic->count++;
	}

	return 0;
}