1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996,2008 Oracle.  All rights reserved.
5 *
6 * $Id: lock_util.c,v 12.11 2008/01/08 20:58:41 bostic Exp $
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.  So, we use the XOR of the page number and the first four bytes of
30 * the file id to produce a 32-bit hash value.
31 *
32 * We have no particular reason to believe that this algorithm will produce
33 * a good hash, but we want a fast hash more than we want a good one, when
34 * we're coming through this code path.
35 */
36#define	FAST_HASH(P) {			\
37	u_int32_t __h;			\
38	u_int8_t *__cp, *__hp;		\
39	__hp = (u_int8_t *)&__h;	\
40	__cp = (u_int8_t *)(P);		\
41	__hp[0] = __cp[0] ^ __cp[4];	\
42	__hp[1] = __cp[1] ^ __cp[5];	\
43	__hp[2] = __cp[2] ^ __cp[6];	\
44	__hp[3] = __cp[3] ^ __cp[7];	\
45	return (__h);			\
46}
47
48/*
49 * __lock_ohash --
50 *
51 * PUBLIC: u_int32_t __lock_ohash __P((const DBT *));
52 */
53u_int32_t
54__lock_ohash(dbt)
55	const DBT *dbt;
56{
57	if (dbt->size == sizeof(DB_LOCK_ILOCK))
58		FAST_HASH(dbt->data);
59
60	return (__ham_func5(NULL, dbt->data, dbt->size));
61}
62
63/*
64 * __lock_lhash --
65 *
66 * PUBLIC: u_int32_t __lock_lhash __P((DB_LOCKOBJ *));
67 */
68u_int32_t
69__lock_lhash(lock_obj)
70	DB_LOCKOBJ *lock_obj;
71{
72	void *obj_data;
73
74	obj_data = SH_DBT_PTR(&lock_obj->lockobj);
75
76	if (lock_obj->lockobj.size == sizeof(DB_LOCK_ILOCK))
77		FAST_HASH(obj_data);
78
79	return (__ham_func5(NULL, obj_data, lock_obj->lockobj.size));
80}
81
82/*
83 * __lock_nomem --
84 *	Report a lack of some resource.
85 *
86 * PUBLIC: int __lock_nomem __P((ENV *, const char *));
87 */
88int
89__lock_nomem(env, res)
90	ENV *env;
91	const char *res;
92{
93	__db_errx(env, "Lock table is out of available %s", res);
94	return (ENOMEM);
95}
96