1 /*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996, 2013 Oracle and/or its affiliates. All rights reserved.
5 *
6 * $Id$
7 */
8
9 #include "db_config.h"
10
11 #include "db_int.h"
12 #include "dbinc/db_page.h"
13 #include "dbinc/hash.h"
14 #include "dbinc/lock.h"
15
16 /*
17 * The next two functions are the hash functions used to store objects in the
18 * lock hash tables. They are hashing the same items, but one (__lock_ohash)
19 * takes a DBT (used for hashing a parameter passed from the user) and the
20 * other (__lock_lhash) takes a DB_LOCKOBJ (used for hashing something that is
21 * already in the lock manager). In both cases, we have a special check to
22 * fast path the case where we think we are doing a hash on a DB page/fileid
23 * pair. If the size is right, then we do the fast hash.
24 *
25 * We know that DB uses DB_LOCK_ILOCK types for its lock objects. The first
26 * four bytes are the 4-byte page number and the next DB_FILE_ID_LEN bytes
27 * are a unique file id, where the first 4 bytes on UNIX systems are the file
28 * inode number, and the first 4 bytes on Windows systems are the FileIndexLow
29 * bytes. This is followed by a random number. The inode values tend
30 * to increment fairly slowly and are not good for hashing. So, we use
31 * the XOR of the page number and the four bytes of the file id random
32 * number to produce a 32-bit hash value.
33 *
34 * We have no particular reason to believe that this algorithm will produce
35 * a good hash, but we want a fast hash more than we want a good one, when
36 * we're coming through this code path.
37 */
38 #define FAST_HASH(P) { \
39 u_int32_t __h; \
40 u_int8_t *__cp, *__hp; \
41 __hp = (u_int8_t *)&__h; \
42 __cp = (u_int8_t *)(P); \
43 __hp[0] = __cp[0] ^ __cp[12]; \
44 __hp[1] = __cp[1] ^ __cp[13]; \
45 __hp[2] = __cp[2] ^ __cp[14]; \
46 __hp[3] = __cp[3] ^ __cp[15]; \
47 return (__h); \
48 }
49
50 /*
51 * __lock_ohash --
52 *
53 * PUBLIC: u_int32_t __lock_ohash __P((const DBT *));
54 */
55 u_int32_t
__lock_ohash(dbt)56 __lock_ohash(dbt)
57 const DBT *dbt;
58 {
59 if (dbt->size == sizeof(DB_LOCK_ILOCK))
60 FAST_HASH(dbt->data);
61
62 return (__ham_func5(NULL, dbt->data, dbt->size));
63 }
64
65 /*
66 * __lock_lhash --
67 *
68 * PUBLIC: u_int32_t __lock_lhash __P((DB_LOCKOBJ *));
69 */
70 u_int32_t
__lock_lhash(lock_obj)71 __lock_lhash(lock_obj)
72 DB_LOCKOBJ *lock_obj;
73 {
74 void *obj_data;
75
76 obj_data = SH_DBT_PTR(&lock_obj->lockobj);
77
78 if (lock_obj->lockobj.size == sizeof(DB_LOCK_ILOCK))
79 FAST_HASH(obj_data);
80
81 return (__ham_func5(NULL, obj_data, lock_obj->lockobj.size));
82 }
83
84 /*
85 * __lock_nomem --
86 * Report a lack of some resource.
87 *
88 * PUBLIC: int __lock_nomem __P((ENV *, const char *));
89 */
90 int
__lock_nomem(env,res)91 __lock_nomem(env, res)
92 ENV *env;
93 const char *res;
94 {
95 __db_errx(env, DB_STR_A("2055", "Lock table is out of available %s",
96 "%s"), res);
97 return (ENOMEM);
98 }
99