1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996, 1997, 1998
5 *	Sleepycat Software.  All rights reserved.
6 */
7/*
8 * Copyright (c) 1990, 1993
9 *	Margo Seltzer.  All rights reserved.
10 */
11/*
12 * Copyright (c) 1990, 1993
13 *	The Regents of the University of California.  All rights reserved.
14 *
15 * This code is derived from software contributed to Berkeley by
16 * Margo Seltzer.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in the
25 *    documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 *    must display the following acknowledgement:
28 *	This product includes software developed by the University of
29 *	California, Berkeley and its contributors.
30 * 4. Neither the name of the University nor the names of its contributors
31 *    may be used to endorse or promote products derived from this software
32 *    without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 */
46
47#include "config.h"
48
49#ifndef lint
50static const char sccsid[] = "@(#)hsearch.c	10.9 (Sleepycat) 4/18/98";
51#endif /* not lint */
52
53#ifndef NO_SYSTEM_INCLUDES
54#include <sys/types.h>
55
56#include <errno.h>
57#include <string.h>
58#endif
59
60#define	DB_DBM_HSEARCH	1
61#include "db_int.h"
62
63static DB	*dbp;
64static ENTRY	 retval;
65
66int
67__db_hcreate(nel)
68	size_t nel;
69{
70	DB_INFO dbinfo;
71
72	memset(&dbinfo, 0, sizeof(dbinfo));
73	dbinfo.db_pagesize = 512;
74	dbinfo.h_ffactor = 16;
75	dbinfo.h_nelem = (u_int32_t)nel;	/* XXX: Possible overflow. */
76
77	errno = db_open(NULL,
78	    DB_HASH, DB_CREATE, __db_omode("rw----"), NULL, &dbinfo, &dbp);
79	return (errno == 0 ? 1 : 0);
80}
81
82ENTRY *
83__db_hsearch(item, action)
84	ENTRY item;
85	ACTION action;
86{
87	DBT key, val;
88
89	if (dbp == NULL) {
90		errno = EINVAL;
91		return (NULL);
92	}
93	memset(&key, 0, sizeof(key));
94	memset(&val, 0, sizeof(val));
95	key.data = item.key;
96	key.size = strlen(item.key) + 1;
97
98	switch (action) {
99	case ENTER:
100		val.data = item.data;
101		val.size = strlen(item.data) + 1;
102
103		/*
104		 * Try and add the key to the database.  If we fail because
105		 * the key already exists, return the existing key.
106		 */
107		if ((errno =
108		    dbp->put(dbp, NULL, &key, &val, DB_NOOVERWRITE)) == 0)
109			break;
110		if (errno != DB_KEYEXIST)
111			return (NULL);
112		if ((errno = dbp->get(dbp, NULL, &key, &val, 0)) == 0)
113			break;
114
115		if (errno == DB_NOTFOUND)	/* XXX: can't happen. */
116			errno = EINVAL;
117		break;
118	case FIND:
119		if ((errno = dbp->get(dbp, NULL, &key, &val, 0)) != 0) {
120			if (errno == DB_NOTFOUND)
121				errno = 0;
122			return (NULL);
123		}
124		item.data = (char *)val.data;
125		break;
126	default:
127		errno = EINVAL;
128		return (NULL);
129	}
130	retval.key = item.key;
131	retval.data = item.data;
132	return (&retval);
133}
134
135void
136__db_hdestroy()
137{
138	if (dbp != NULL) {
139		(void)dbp->close(dbp, 0);
140		dbp = NULL;
141	}
142}
143