00001 /*- 00002 * See the file LICENSE for redistribution information. 00003 * 00004 * Copyright (c) 1996, 1997, 1998, 1999, 2000 00005 * Sleepycat Software. All rights reserved. 00006 */ 00007 00008 #include "config.h" 00009 00010 #ifndef lint 00011 static const char revid[] = "$Id: lock__util_8c-source.html,v 1.1 2008年06月08日 10:20:06 sebdiaz Exp $"; 00012 #endif /* not lint */ 00013 00014 #ifndef NO_SYSTEM_INCLUDES 00015 #include <sys/types.h> 00016 00017 #include <string.h> 00018 #endif 00019 00020 #include "db_int.h" 00021 #include "db_page.h" 00022 #include "db_shash.h" 00023 #include "hash.h" 00024 #include "lock.h" 00025 00026 /* 00027 * CDB___lock_cmp -- 00028 * This function is used to compare a DBT that is about to be entered 00029 * into a hash table with an object already in the hash table. Note 00030 * that it just returns true on equal and 0 on not-equal. Therefore 00031 * this function cannot be used as a sort function; its purpose is to 00032 * be used as a hash comparison function. 00033 * 00034 * PUBLIC: int CDB___lock_cmp __P((const DBT *, DB_LOCKOBJ *)); 00035 */ 00036 int 00037 CDB___lock_cmp(dbt, lock_obj) 00038 const DBT *dbt; 00039 DB_LOCKOBJ *lock_obj; 00040 { 00041 void *obj_data; 00042 00043 obj_data = SH_DBT_PTR(&lock_obj->lockobj); 00044 return (dbt->size == lock_obj->lockobj.size && 00045 memcmp(dbt->data, obj_data, dbt->size) == 0); 00046 } 00047 00048 /* 00049 * PUBLIC: int CDB___lock_locker_cmp __P((u_int32_t, DB_LOCKER *)); 00050 */ 00051 int 00052 CDB___lock_locker_cmp(locker, sh_locker) 00053 u_int32_t locker; 00054 DB_LOCKER *sh_locker; 00055 { 00056 return (locker == sh_locker->id); 00057 } 00058 00059 /* 00060 * The next two functions are the hash functions used to store objects in the 00061 * lock hash tables. They are hashing the same items, but one (CDB___lock_ohash) 00062 * takes a DBT (used for hashing a parameter passed from the user) and the 00063 * other (CDB___lock_lhash) takes a DB_LOCKOBJ (used for hashing something that is 00064 * already in the lock manager). In both cases, we have a special check to 00065 * fast path the case where we think we are doing a hash on a DB page/fileid 00066 * pair. If the size is right, then we do the fast hash. 00067 * 00068 * We know that DB uses DB_LOCK_ILOCK types for its lock objects. The first 00069 * four bytes are the 4-byte page number and the next DB_FILE_ID_LEN bytes 00070 * are a unique file id, where the first 4 bytes on UNIX systems are the file 00071 * inode number, and the first 4 bytes on Windows systems are the FileIndexLow 00072 * bytes. So, we use the XOR of the page number and the first four bytes of 00073 * the file id to produce a 32-bit hash value. 00074 * 00075 * We have no particular reason to believe that this algorithm will produce 00076 * a good hash, but we want a fast hash more than we want a good one, when 00077 * we're coming through this code path. 00078 */ 00079 #define FAST_HASH(P) { \ 00080 u_int32_t __h; \ 00081 u_int8_t *__cp, *__hp; \ 00082 __hp = (u_int8_t *)&__h; \ 00083 __cp = (u_int8_t *)(P); \ 00084 __hp[0] = __cp[0] ^ __cp[4]; \ 00085 __hp[1] = __cp[1] ^ __cp[5]; \ 00086 __hp[2] = __cp[2] ^ __cp[6]; \ 00087 __hp[3] = __cp[3] ^ __cp[7]; \ 00088 return (__h); \ 00089 } 00090 00091 /* 00092 * CDB___lock_ohash -- 00093 * 00094 * PUBLIC: u_int32_t CDB___lock_ohash __P((const DBT *)); 00095 */ 00096 u_int32_t 00097 CDB___lock_ohash(dbt) 00098 const DBT *dbt; 00099 { 00100 if (dbt->size == sizeof(DB_LOCK_ILOCK)) 00101 FAST_HASH(dbt->data); 00102 00103 return (CDB___ham_func5(dbt->data, dbt->size)); 00104 } 00105 00106 /* 00107 * CDB___lock_lhash -- 00108 * 00109 * PUBLIC: u_int32_t CDB___lock_lhash __P((DB_LOCKOBJ *)); 00110 */ 00111 u_int32_t 00112 CDB___lock_lhash(lock_obj) 00113 DB_LOCKOBJ *lock_obj; 00114 { 00115 void *obj_data; 00116 00117 obj_data = SH_DBT_PTR(&lock_obj->lockobj); 00118 00119 if (lock_obj->lockobj.size == sizeof(DB_LOCK_ILOCK)) 00120 FAST_HASH(obj_data); 00121 00122 return (CDB___ham_func5(obj_data, lock_obj->lockobj.size)); 00123 } 00124 00125 /* 00126 * CDB___lock_locker_hash -- 00127 * Hash function for entering lockers into the locker hash table. 00128 * Since these are simply 32-bit unsigned integers, just return 00129 * the locker value. 00130 * 00131 * PUBLIC: u_int32_t CDB___lock_locker_hash __P((u_int32_t)); 00132 */ 00133 u_int32_t 00134 CDB___lock_locker_hash(locker) 00135 u_int32_t locker; 00136 { 00137 return (locker); 00138 }