/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*
* Copyright 1988-2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <malloc.h>
#include "db_headers.h"
#include "db_index.h"
#include "db_pickle.h"
#include "nisdb_mt.h"
#include "nisdb_rw.h"
11,
113,
337,
977,
2053,
4073,
8011,
16001,
0
};
// prevents wrap around numbers from being passed
/* Constructor: creates empty index. */
{
table_size = 0;
count = 0;
case_insens = FALSE;
/* grow(); */
}
/* Destructor: deletes index, including all associated db_index_entry. */
{
WRITELOCKV(this, "w db_index::~db_index");
reset();
}
/* Get rid of table and all associated entries, and reset counters */
void
{
int i;
WRITELOCKV(this, "w db_index::reset");
/* Add sanity test in case table was corrupted */
for (i = 0; i < table_size; i++) { // go through table
n = curr->getnextentry();
delete curr;
curr = n;
}
}
}
delete tab; // get rid of table itself
table_size = count = 0;
WRITEUNLOCKV(this, "wu db_index::reset");
}
/*
* Initialize index according to the specification of the key descriptor
* Currently, only affects case_insens flag of index.
*/
void
{
WRITELOCKV(this, "w db_index::init");
if ((k->key_flags)&DB_KEY_CASE)
case_insens = TRUE;
WRITEUNLOCKV(this, "wu db_index::init");
}
/* Returns the next size to use for the hash table */
static long unsigned
{
long unsigned newsize = 0, n;
if (oldsize == 0)
else {
break;
}
if (newsize == 0)
}
return (newsize);
}
/*
* Grow the current hashtable upto the next size.
* The contents of the existing hashtable is copied to the new one and
* relocated according to its hashvalue relative to the new size.
* Old table is deleted after the relocation.
*/
void
{
WRITELOCKV(this, "w db_index::grow");
#ifdef DEBUG
if (debug > 3)
#endif
if (table_size > CALLOC_LIMIT) {
WRITEUNLOCKV(this,
"wu db_index::grow: table size exceeds calloc limit");
FATAL("db_index::grow: table size exceeds calloc limit",
}
if ((tab = (db_index_entry_p*)
calloc((unsigned int) table_size,
sizeof (db_index_entry_p))) == NULL) {
WRITEUNLOCKV(this,
"wu db_index::grow: cannot allocate space");
}
for (i = 0; i < oldsize; i++) {
}
delete oldtab; // delete old hashtable
}
WRITEUNLOCKV(this, "wu db_index::grow");
}
/*
* Look up given index value in hashtable.
* Return pointer to db_index_entries that match the given value, linked
* via the 'next_result' pointer. Return in 'how_many_found' the size
* of this list. Return NULL if not found.
*/
{
register unsigned long hval;
unsigned long bucket;
return (NULL);
}
else
}
return (ret);
}
/*
* Remove the entry with the given index value and location 'recnum'.
* If successful, return DB_SUCCESS; otherwise DB_NOTUNIQUE if index_value
* is null; DB_NOTFOUND if entry is not found.
* If successful, decrement count of number of entries in hash table.
*/
{
register unsigned long hval;
unsigned long bucket;
if (index_value == NULL)
return (DB_NOTUNIQUE);
return (DB_NOTFOUND);
}
ret = DB_NOTFOUND;
recnum)) {
--count;
ret = DB_SUCCESS;
} else
ret = DB_NOTFOUND;
return (ret);
}
/*
* Add a new index entry with the given index value and location 'recnum'.
* Return DB_NOTUNIQUE, if entry with identical index_value and recnum
* already exists. If entry is added, return DB_SUCCESS.
* Increment count of number of entries in index table and grow table
* if number of entries equals size of table.
* Note that a copy of index_value is made for new entry.
*/
{
register unsigned long hval;
if (index_value == NULL)
return (DB_NOTUNIQUE);
unsigned long bucket;
WRITEUNLOCK(this, DB_MEMORY_LIMIT,
"wu db_index::add");
FATAL3("db_index::add: cannot allocate space",
}
/* do nothing */
} else {
return (DB_NOTUNIQUE);
}
/* increase hash table size if number of entries equals table size */
if (++count > table_size)
grow();
return (DB_SUCCESS);
}
/* ************************* pickle_index ********************* */
static bool_t
{
}
public:
};
/* Dumps this index to named file. */
int
{
int ret;
if (status == 1)
else
}
/*
* Constructor: creates index by loading it from the specified file.
* If loading fails, creates empty index.
*/
{
table_size = count = 0;
/* load new hashbuf */
if (f.transfer(this) < 0) {
/* Load failed; reset. */
table_size = count = 0;
}
}
/*
* Return in 'tsize' the table_size, and 'tcount' the number of entries
* in the table.
*/
void
{
READLOCKV(this, "r db_index::stats");
*tsize = table_size;
READUNLOCKV(this, "ru db_index::stats");
}
/* Print all entries in the table. */
void
{
long i;
READLOCKV(this, "r db_index::print");
/* Add sanity check in case table corrupted */
for (i = 0; i < table_size; i++) {
}
}
READUNLOCKV(this, "ru db_index::print");
}
/*
* Moves an index from an xdr index. Upon completion, original index's tab
* will be NULL.
*/
{
orig->table_size = 0;
return (DB_SUCCESS);
}