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
50 static 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 
63 static DB	*dbp;
64 static ENTRY	 retval;
65 
66 int
__db_hcreate(nel)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 
82 ENTRY *
__db_hsearch(item,action)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 
135 void
__db_hdestroy()136 __db_hdestroy()
137 {
138 	if (dbp != NULL) {
139 		(void)dbp->close(dbp, 0);
140 		dbp = NULL;
141 	}
142 }
143