8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.25 2000/04/12 17:14:44 momjian Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.26 2000/06/05 07:28:35 tgl Exp $
12
12
*
13
13
* NOTES
14
14
* These functions are stored in pg_amproc. For each operator class
21
21
22
22
#include "access/hash.h"
23
23
24
- uint32
25
- hashint2 (int16 key )
24
+ Datum
25
+ hashint2 (PG_FUNCTION_ARGS )
26
26
{
27
- return ( uint32 ) ~key ;
27
+ PG_RETURN_UINT32 (( uint32 ) ~ PG_GETARG_INT16 ( 0 )) ;
28
28
}
29
29
30
- uint32
31
- hashint4 (uint32 key )
30
+ Datum
31
+ hashint4 (PG_FUNCTION_ARGS )
32
32
{
33
- return ~ key ;
33
+ PG_RETURN_UINT32 (~ PG_GETARG_UINT32 ( 0 )) ;
34
34
}
35
35
36
- uint32
37
- hashint8 (int64 * key )
36
+ Datum
37
+ hashint8 (PG_FUNCTION_ARGS )
38
38
{
39
- return ~((uint32 ) * key );
39
+ /* we just use the low 32 bits... */
40
+ PG_RETURN_UINT32 (~((uint32 ) PG_GETARG_INT64 (0 )));
40
41
}
41
42
42
43
/* Hash function from Chris Torek. */
43
- uint32
44
- hashfloat4 (float32 keyp )
44
+ Datum
45
+ hashfloat4 (PG_FUNCTION_ARGS )
45
46
{
46
- int len ;
47
+ float4 key = PG_GETARG_FLOAT4 (0 );
48
+ char * kp = (char * ) & key ;
49
+ int len = sizeof (key );
47
50
int loop ;
48
51
uint32 h ;
49
- char * kp = (char * ) keyp ;
50
-
51
- len = sizeof (float32data );
52
52
53
53
#define HASH4a h = (h << 5) - h + *kp++;
54
54
#define HASH4b h = (h << 5) + h + *kp++;
55
55
#define HASH4 HASH4b
56
56
57
-
58
57
h = 0 ;
59
- if (len > 0 )
60
- {
61
- loop = (len + 8 - 1 ) >> 3 ;
58
+ /*
59
+ * This is a tad silly, given that we expect len = 4, but a smart
60
+ * compiler should be able to eliminate the redundant code...
61
+ */
62
+ loop = (len + 8 - 1 ) >> 3 ;
62
63
63
- switch (len & (8 - 1 ))
64
- {
65
- case 0 :
66
- do
67
- { /* All fall throughs */
68
- HASH4 ;
69
- case 7 :
70
- HASH4 ;
71
- case 6 :
72
- HASH4 ;
73
- case 5 :
74
- HASH4 ;
75
- case 4 :
76
- HASH4 ;
77
- case 3 :
78
- HASH4 ;
79
- case 2 :
80
- HASH4 ;
81
- case 1 :
82
- HASH4 ;
83
- } while (-- loop );
84
- }
64
+ switch (len & (8 - 1 ))
65
+ {
66
+ case 0 :
67
+ do
68
+ { /* All fall throughs */
69
+ HASH4 ;
70
+ case 7 :
71
+ HASH4 ;
72
+ case 6 :
73
+ HASH4 ;
74
+ case 5 :
75
+ HASH4 ;
76
+ case 4 :
77
+ HASH4 ;
78
+ case 3 :
79
+ HASH4 ;
80
+ case 2 :
81
+ HASH4 ;
82
+ case 1 :
83
+ HASH4 ;
84
+ } while (-- loop );
85
85
}
86
- return h ;
86
+ PG_RETURN_UINT32 ( h ) ;
87
87
}
88
88
89
-
90
- uint32
91
- hashfloat8 (float64 keyp )
89
+ Datum
90
+ hashfloat8 (PG_FUNCTION_ARGS )
92
91
{
93
- int len ;
92
+ float8 key = PG_GETARG_FLOAT8 (0 );
93
+ char * kp = (char * ) & key ;
94
+ int len = sizeof (key );
94
95
int loop ;
95
96
uint32 h ;
96
- char * kp = (char * ) keyp ;
97
-
98
- len = sizeof (float64data );
99
97
100
98
#define HASH4a h = (h << 5) - h + *kp++;
101
99
#define HASH4b h = (h << 5) + h + *kp++;
102
100
#define HASH4 HASH4b
103
101
104
-
105
102
h = 0 ;
106
- if (len > 0 )
107
- {
108
- loop = (len + 8 - 1 ) >> 3 ;
103
+ /*
104
+ * This is a tad silly, given that we expect len = 8, but a smart
105
+ * compiler should be able to eliminate the redundant code...
106
+ */
107
+ loop = (len + 8 - 1 ) >> 3 ;
109
108
110
- switch (len & (8 - 1 ))
111
- {
112
- case 0 :
113
- do
114
- { /* All fall throughs */
115
- HASH4 ;
116
- case 7 :
117
- HASH4 ;
118
- case 6 :
119
- HASH4 ;
120
- case 5 :
121
- HASH4 ;
122
- case 4 :
123
- HASH4 ;
124
- case 3 :
125
- HASH4 ;
126
- case 2 :
127
- HASH4 ;
128
- case 1 :
129
- HASH4 ;
130
- } while (-- loop );
131
- }
109
+ switch (len & (8 - 1 ))
110
+ {
111
+ case 0 :
112
+ do
113
+ { /* All fall throughs */
114
+ HASH4 ;
115
+ case 7 :
116
+ HASH4 ;
117
+ case 6 :
118
+ HASH4 ;
119
+ case 5 :
120
+ HASH4 ;
121
+ case 4 :
122
+ HASH4 ;
123
+ case 3 :
124
+ HASH4 ;
125
+ case 2 :
126
+ HASH4 ;
127
+ case 1 :
128
+ HASH4 ;
129
+ } while (-- loop );
132
130
}
133
- return h ;
131
+ PG_RETURN_UINT32 ( h ) ;
134
132
}
135
133
136
-
137
- uint32
138
- hashoid (Oid key )
134
+ Datum
135
+ hashoid (PG_FUNCTION_ARGS )
139
136
{
140
- return ( uint32 ) ~ key ;
137
+ PG_RETURN_UINT32 (~( uint32 ) PG_GETARG_OID ( 0 )) ;
141
138
}
142
139
143
- uint32
144
- hashoidvector (Oid * key )
140
+ Datum
141
+ hashoidvector (PG_FUNCTION_ARGS )
145
142
{
143
+ Oid * key = (Oid * ) PG_GETARG_POINTER (0 );
146
144
int i ;
147
145
uint32 result = 0 ;
148
146
149
147
for (i = INDEX_MAX_KEYS ; -- i >= 0 ;)
150
148
result = (result << 1 ) ^ (~(uint32 ) key [i ]);
151
- return result ;
149
+ PG_RETURN_UINT32 ( result ) ;
152
150
}
153
151
154
152
/*
155
153
* Note: hashint2vector currently can't be used as a user hash table
156
154
* hash function, because it has no pg_proc entry. We only need it
157
155
* for catcache indexing.
158
156
*/
159
- uint32
160
- hashint2vector (int16 * key )
157
+ Datum
158
+ hashint2vector (PG_FUNCTION_ARGS )
161
159
{
160
+ int16 * key = (int16 * ) PG_GETARG_POINTER (0 );
162
161
int i ;
163
162
uint32 result = 0 ;
164
163
165
164
for (i = INDEX_MAX_KEYS ; -- i >= 0 ;)
166
165
result = (result << 1 ) ^ (~(uint32 ) key [i ]);
167
- return result ;
166
+ PG_RETURN_UINT32 ( result ) ;
168
167
}
169
168
170
169
171
170
#define PRIME1 37
172
171
#define PRIME2 1048583
173
172
174
- uint32
175
- hashchar (char key )
173
+ Datum
174
+ hashchar (PG_FUNCTION_ARGS )
176
175
{
177
176
uint32 h ;
178
177
179
178
/* Convert char to integer */
180
- h = (key - ' ' );
179
+ h = (PG_GETARG_CHAR ( 0 ) - ' ' );
181
180
h %= PRIME2 ;
182
181
183
- return h ;
182
+ PG_RETURN_UINT32 ( h ) ;
184
183
}
185
184
186
-
187
- uint32
188
- hashname (NameData * n )
185
+ Datum
186
+ hashname (PG_FUNCTION_ARGS )
189
187
{
188
+ char * key = NameStr (* PG_GETARG_NAME (0 ));
189
+ int len = NAMEDATALEN ;
190
190
uint32 h ;
191
- int len ;
192
- char * key ;
193
-
194
- key = NameStr (* n );
195
191
196
192
h = 0 ;
197
- len = NAMEDATALEN ;
198
193
/* Convert string to integer */
199
194
while (len -- )
200
195
h = h * PRIME1 ^ (* key ++ - ' ' );
201
196
h %= PRIME2 ;
202
197
203
- return h ;
198
+ PG_RETURN_UINT32 ( h ) ;
204
199
}
205
200
206
-
207
-
208
201
/*
209
202
* (Comment from the original db3 hashing code: )
210
203
*
@@ -216,19 +209,17 @@ hashname(NameData *n)
216
209
*
217
210
* "OZ's original sdbm hash"
218
211
*/
219
- uint32
220
- hashtext (struct varlena * key )
212
+ Datum
213
+ hashtext (PG_FUNCTION_ARGS )
221
214
{
215
+ text * key = PG_GETARG_TEXT_P (0 );
222
216
int keylen ;
223
217
char * keydata ;
224
218
uint32 n ;
225
219
int loop ;
226
220
227
221
keydata = VARDATA (key );
228
- keylen = VARSIZE (key );
229
-
230
- /* keylen includes the four bytes in which string keylength is stored */
231
- keylen -= sizeof (VARSIZE (key ));
222
+ keylen = VARSIZE (key ) - VARHDRSZ ;
232
223
233
224
#define HASHC n = *keydata++ + 65599 * n
234
225
@@ -260,5 +251,5 @@ hashtext(struct varlena * key)
260
251
} while (-- loop );
261
252
}
262
253
}
263
- return n ;
254
+ PG_RETURN_UINT32 ( n ) ;
264
255
}
0 commit comments