]> git.saurik.com Git - apple/libc.git/blob - libdarwin/stdlib.c
d718a94e59e62b5c6b91f0ec894bc1fdb07aec15
[apple/libc.git] / libdarwin / stdlib.c
1 /*
2 * Copyright (c) 2018 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 #include "internal.h"
24
25 #pragma mark API
26 void
27 os_localtime_file(char buff[32])
28 {
29 struct timeval tv;
30 struct tm curtime;
31
32 posix_assert_zero(gettimeofday(&tv, NULL));
33 (void)localtime_r(&tv.tv_sec, &curtime);
34
35 // Return a time representation that is ideal for use in filenames, so no
36 // spaces or things that need to be escaped.
37 snprintf(buff, 32, "%d-%02d-%02d_%02d.%02d.%02d.%06d",
38 curtime.tm_year + 1900, curtime.tm_mon + 1, curtime.tm_mday,
39 curtime.tm_hour, curtime.tm_min, curtime.tm_sec, tv.tv_usec);
40 }
41
42 // MurmurHash2 was written by Austin Appleby, and is placed in the public
43 // domain. The author hereby disclaims copyright to this source code.
44 uint64_t
45 os_simple_hash(const void *buff, size_t len)
46 {
47 const uint64_t seed = 0;
48 #ifdef __LP64__
49 // MurmurHash64A
50 const uint64_t m = 0xc6a4a7935bd1e995;
51 const int r = 47;
52 uint64_t h = seed ^ (len * m);
53 const uint64_t * data = (const uint64_t *)buff;
54 const uint64_t * end = data + (len / 8);
55 while(data != end) {
56 uint64_t k = *data++;
57 k *= m;
58 k ^= k >> r;
59 k *= m;
60 h ^= k;
61 h *= m;
62 }
63 const unsigned char * data2 = (const unsigned char *)data;
64 switch(len & 7) {
65 case 7: h ^= ((uint64_t)data2[6]) << 48;
66 case 6: h ^= ((uint64_t)data2[5]) << 40;
67 case 5: h ^= ((uint64_t)data2[4]) << 32;
68 case 4: h ^= ((uint64_t)data2[3]) << 24;
69 case 3: h ^= ((uint64_t)data2[2]) << 16;
70 case 2: h ^= ((uint64_t)data2[1]) << 8;
71 case 1: h ^= ((uint64_t)data2[0]);
72 h *= m;
73 };
74 h ^= h >> r;
75 h *= m;
76 h ^= h >> r;
77 #else // __LP64__
78 // MurmurHash64B
79 const uint32_t m = 0x5bd1e995;
80 const int r = 24;
81
82 uint32_t h1 = (uint32_t)(seed) ^ len;
83 uint32_t h2 = (uint32_t)(seed >> 32);
84
85 const uint32_t * data = (const uint32_t *)buff;
86
87 #define MIX(k, h) \
88 (k) *= m; (k) ^= (k) >> r; (k) *= m; (h) *= m; (h) ^= (k); len -= 4;
89
90 while(len >= 8) {
91 uint32_t k[2];
92 memcpy(k, (const char*)data, sizeof(k));
93 data += sizeof(k)/sizeof(k[0]);
94
95 MIX(k[0], h1)
96 MIX(k[1], h2)
97 }
98
99 if(len >= 4) {
100 uint32_t k[1];
101 memcpy(k, (const char *)data, sizeof(k));
102 data += sizeof(k)/sizeof(k[0]);
103
104 MIX(k[0], h1);
105 }
106
107 #undef MIX
108
109 switch(len) {
110 case 3: h2 ^= ((unsigned char*)data)[2] << 16;
111 case 2: h2 ^= ((unsigned char*)data)[1] << 8;
112 case 1: h2 ^= ((unsigned char*)data)[0];
113 h2 *= m;
114 };
115
116 h1 ^= h2 >> 18; h1 *= m;
117 h2 ^= h1 >> 22; h2 *= m;
118 h1 ^= h2 >> 17; h1 *= m;
119 h2 ^= h1 >> 19; h2 *= m;
120
121 uint64_t h = h1;
122
123 h = (h << 32) | h2;
124 #endif // __LP64__
125 return h;
126 }
127
128 uint64_t
129 os_simple_hash_string(const char *string)
130 {
131 size_t len = strlen(string);
132 return os_simple_hash(string, len);
133 }