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