1 | /* Copyright (c) 1997-2021 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. |
3 | Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <nss.h> |
20 | |
21 | /* This is from libc/db/hash/hash_func.c, hash3 is static there */ |
22 | /* |
23 | * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte |
24 | * units. On the first time through the loop we get the "leftover bytes" |
25 | * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle |
26 | * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If |
27 | * this routine is heavily used enough, it's worth the ugly coding. |
28 | * |
29 | * OZ's original sdbm hash |
30 | */ |
31 | uint32_t |
32 | __nss_hash (const void *keyarg, size_t len) |
33 | { |
34 | const unsigned char *key; |
35 | size_t loop; |
36 | uint32_t h; |
37 | |
38 | #define HASHC h = *key++ + 65599 * h |
39 | |
40 | h = 0; |
41 | key = keyarg; |
42 | if (len > 0) |
43 | { |
44 | loop = (len + 8 - 1) >> 3; |
45 | switch (len & (8 - 1)) |
46 | { |
47 | case 0: |
48 | do |
49 | { |
50 | HASHC; |
51 | /* FALLTHROUGH */ |
52 | case 7: |
53 | HASHC; |
54 | /* FALLTHROUGH */ |
55 | case 6: |
56 | HASHC; |
57 | /* FALLTHROUGH */ |
58 | case 5: |
59 | HASHC; |
60 | /* FALLTHROUGH */ |
61 | case 4: |
62 | HASHC; |
63 | /* FALLTHROUGH */ |
64 | case 3: |
65 | HASHC; |
66 | /* FALLTHROUGH */ |
67 | case 2: |
68 | HASHC; |
69 | /* FALLTHROUGH */ |
70 | case 1: |
71 | HASHC; |
72 | } |
73 | while (--loop); |
74 | } |
75 | } |
76 | return h; |
77 | } |
78 | |
79 | libc_hidden_def (__nss_hash) |
80 | |