native-vector-store 0.3.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +55 -3
  2. package/binding.gyp +3 -2
  3. package/deps/parallel_hashmap/btree.h +4076 -0
  4. package/deps/parallel_hashmap/meminfo.h +195 -0
  5. package/deps/parallel_hashmap/phmap.h +5236 -0
  6. package/deps/parallel_hashmap/phmap_base.h +5115 -0
  7. package/deps/parallel_hashmap/phmap_bits.h +665 -0
  8. package/deps/parallel_hashmap/phmap_config.h +790 -0
  9. package/deps/parallel_hashmap/phmap_dump.h +335 -0
  10. package/deps/parallel_hashmap/phmap_fwd_decl.h +186 -0
  11. package/deps/parallel_hashmap/phmap_utils.h +407 -0
  12. package/docs/index.html +52 -3
  13. package/lib/index.d.ts +35 -1
  14. package/package.json +1 -1
  15. package/prebuilds/darwin-arm64/native-vector-store.node +0 -0
  16. package/prebuilds/darwin-x64/native-vector-store.node +0 -0
  17. package/prebuilds/linux-arm64/native-vector-store.node +0 -0
  18. package/prebuilds/linux-x64/native-vector-store.node +0 -0
  19. package/src/Makefile +26 -6
  20. package/src/binding.cc +185 -2
  21. package/src/english_abbreviations.h +197 -0
  22. package/src/english_dictionary.h +25185 -0
  23. package/src/english_punctuations.h +42 -0
  24. package/src/english_stop_words.h +434 -0
  25. package/src/simple_sentence_splitter.h +218 -0
  26. package/src/simple_tokenizer.cpp +92 -0
  27. package/src/simple_tokenizer.h +30 -0
  28. package/src/test_bm25.cpp +357 -0
  29. package/src/test_hybrid_search.cpp +496 -0
  30. package/src/vector_store.cpp +239 -3
  31. package/src/vector_store.h +52 -1
  32. package/src/vector_store_loader.cpp +1 -1
  33. package/src/vector_store_loader_adaptive.cpp +1 -1
  34. package/src/vector_store_loader_mmap.cpp +2 -2
  35. package/prebuilds/win32-x64/native-vector-store.node +0 -0
@@ -0,0 +1,665 @@
1
+ #if !defined(phmap_bits_h_guard_)
2
+ #define phmap_bits_h_guard_
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // Copyright (c) 2019, Gregory Popovitch - greg7mdp@gmail.com
6
+ //
7
+ // Licensed under the Apache License, Version 2.0 (the "License");
8
+ // you may not use this file except in compliance with the License.
9
+ // You may obtain a copy of the License at
10
+ //
11
+ // https://www.apache.org/licenses/LICENSE-2.0
12
+ //
13
+ // Unless required by applicable law or agreed to in writing, software
14
+ // distributed under the License is distributed on an "AS IS" BASIS,
15
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ // See the License for the specific language governing permissions and
17
+ // limitations under the License.
18
+ //
19
+ // Includes work from abseil-cpp (https://github.com/abseil/abseil-cpp)
20
+ // with modifications.
21
+ //
22
+ // Copyright 2018 The Abseil Authors.
23
+ //
24
+ // Licensed under the Apache License, Version 2.0 (the "License");
25
+ // you may not use this file except in compliance with the License.
26
+ // You may obtain a copy of the License at
27
+ //
28
+ // https://www.apache.org/licenses/LICENSE-2.0
29
+ //
30
+ // Unless required by applicable law or agreed to in writing, software
31
+ // distributed under the License is distributed on an "AS IS" BASIS,
32
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33
+ // See the License for the specific language governing permissions and
34
+ // limitations under the License.
35
+ // ---------------------------------------------------------------------------
36
+
37
+ // The following guarantees declaration of the byte swap functions
38
+ #ifdef _MSC_VER
39
+ #include <stdlib.h> // NOLINT(build/include)
40
+ #elif defined(__APPLE__)
41
+ // Mac OS X / Darwin features
42
+ #include <libkern/OSByteOrder.h>
43
+ #elif defined(__FreeBSD__)
44
+ #include <sys/endian.h>
45
+ #elif defined(__GLIBC__)
46
+ #include <byteswap.h> // IWYU pragma: export
47
+ #endif
48
+
49
+ #include <string.h>
50
+ #include <cstdint>
51
+ #include "phmap_config.h"
52
+
53
+ #ifdef _MSC_VER
54
+ #pragma warning(push)
55
+ #pragma warning(disable : 4514) // unreferenced inline function has been removed
56
+ #endif
57
+
58
+ // -----------------------------------------------------------------------------
59
+ // unaligned APIs
60
+ // -----------------------------------------------------------------------------
61
+ // Portable handling of unaligned loads, stores, and copies.
62
+ // On some platforms, like ARM, the copy functions can be more efficient
63
+ // then a load and a store.
64
+ // -----------------------------------------------------------------------------
65
+
66
+ #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||\
67
+ defined(MEMORY_SANITIZER)
68
+ #include <stdint.h>
69
+
70
+ extern "C" {
71
+ uint16_t __sanitizer_unaligned_load16(const void *p);
72
+ uint32_t __sanitizer_unaligned_load32(const void *p);
73
+ uint64_t __sanitizer_unaligned_load64(const void *p);
74
+ void __sanitizer_unaligned_store16(void *p, uint16_t v);
75
+ void __sanitizer_unaligned_store32(void *p, uint32_t v);
76
+ void __sanitizer_unaligned_store64(void *p, uint64_t v);
77
+ } // extern "C"
78
+
79
+ namespace phmap {
80
+ namespace bits {
81
+
82
+ inline uint16_t UnalignedLoad16(const void *p) {
83
+ return __sanitizer_unaligned_load16(p);
84
+ }
85
+
86
+ inline uint32_t UnalignedLoad32(const void *p) {
87
+ return __sanitizer_unaligned_load32(p);
88
+ }
89
+
90
+ inline uint64_t UnalignedLoad64(const void *p) {
91
+ return __sanitizer_unaligned_load64(p);
92
+ }
93
+
94
+ inline void UnalignedStore16(void *p, uint16_t v) {
95
+ __sanitizer_unaligned_store16(p, v);
96
+ }
97
+
98
+ inline void UnalignedStore32(void *p, uint32_t v) {
99
+ __sanitizer_unaligned_store32(p, v);
100
+ }
101
+
102
+ inline void UnalignedStore64(void *p, uint64_t v) {
103
+ __sanitizer_unaligned_store64(p, v);
104
+ }
105
+
106
+ } // namespace bits
107
+ } // namespace phmap
108
+
109
+ #define PHMAP_INTERNAL_UNALIGNED_LOAD16(_p) (phmap::bits::UnalignedLoad16(_p))
110
+ #define PHMAP_INTERNAL_UNALIGNED_LOAD32(_p) (phmap::bits::UnalignedLoad32(_p))
111
+ #define PHMAP_INTERNAL_UNALIGNED_LOAD64(_p) (phmap::bits::UnalignedLoad64(_p))
112
+
113
+ #define PHMAP_INTERNAL_UNALIGNED_STORE16(_p, _val) (phmap::bits::UnalignedStore16(_p, _val))
114
+ #define PHMAP_INTERNAL_UNALIGNED_STORE32(_p, _val) (phmap::bits::UnalignedStore32(_p, _val))
115
+ #define PHMAP_INTERNAL_UNALIGNED_STORE64(_p, _val) (phmap::bits::UnalignedStore64(_p, _val))
116
+
117
+ #else
118
+
119
+ namespace phmap {
120
+ namespace bits {
121
+
122
+ inline uint16_t UnalignedLoad16(const void *p) {
123
+ uint16_t t;
124
+ memcpy(&t, p, sizeof t);
125
+ return t;
126
+ }
127
+
128
+ inline uint32_t UnalignedLoad32(const void *p) {
129
+ uint32_t t;
130
+ memcpy(&t, p, sizeof t);
131
+ return t;
132
+ }
133
+
134
+ inline uint64_t UnalignedLoad64(const void *p) {
135
+ uint64_t t;
136
+ memcpy(&t, p, sizeof t);
137
+ return t;
138
+ }
139
+
140
+ inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); }
141
+
142
+ inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
143
+
144
+ inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
145
+
146
+ } // namespace bits
147
+ } // namespace phmap
148
+
149
+ #define PHMAP_INTERNAL_UNALIGNED_LOAD16(_p) (phmap::bits::UnalignedLoad16(_p))
150
+ #define PHMAP_INTERNAL_UNALIGNED_LOAD32(_p) (phmap::bits::UnalignedLoad32(_p))
151
+ #define PHMAP_INTERNAL_UNALIGNED_LOAD64(_p) (phmap::bits::UnalignedLoad64(_p))
152
+
153
+ #define PHMAP_INTERNAL_UNALIGNED_STORE16(_p, _val) (phmap::bits::UnalignedStore16(_p, _val))
154
+ #define PHMAP_INTERNAL_UNALIGNED_STORE32(_p, _val) (phmap::bits::UnalignedStore32(_p, _val))
155
+ #define PHMAP_INTERNAL_UNALIGNED_STORE64(_p, _val) (phmap::bits::UnalignedStore64(_p, _val))
156
+
157
+ #endif
158
+
159
+ // -----------------------------------------------------------------------------
160
+ // File: optimization.h
161
+ // -----------------------------------------------------------------------------
162
+
163
+ #if defined(__pnacl__)
164
+ #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
165
+ #elif defined(__clang__)
166
+ // Clang will not tail call given inline volatile assembly.
167
+ #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
168
+ #elif defined(__GNUC__)
169
+ // GCC will not tail call given inline volatile assembly.
170
+ #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
171
+ #elif defined(_MSC_VER)
172
+ #include <intrin.h>
173
+ // The __nop() intrinsic blocks the optimisation.
174
+ #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __nop()
175
+ #else
176
+ #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
177
+ #endif
178
+
179
+ #if defined(__GNUC__)
180
+ // Cache line alignment
181
+ #if defined(__i386__) || defined(__x86_64__)
182
+ #define PHMAP_CACHELINE_SIZE 64
183
+ #elif defined(__powerpc64__)
184
+ #define PHMAP_CACHELINE_SIZE 128
185
+ #elif defined(__aarch64__)
186
+ // We would need to read special register ctr_el0 to find out L1 dcache size.
187
+ // This value is a good estimate based on a real aarch64 machine.
188
+ #define PHMAP_CACHELINE_SIZE 64
189
+ #elif defined(__arm__)
190
+ // Cache line sizes for ARM: These values are not strictly correct since
191
+ // cache line sizes depend on implementations, not architectures. There
192
+ // are even implementations with cache line sizes configurable at boot
193
+ // time.
194
+ #if defined(__ARM_ARCH_5T__)
195
+ #define PHMAP_CACHELINE_SIZE 32
196
+ #elif defined(__ARM_ARCH_7A__)
197
+ #define PHMAP_CACHELINE_SIZE 64
198
+ #endif
199
+ #endif
200
+
201
+ #ifndef PHMAP_CACHELINE_SIZE
202
+ // A reasonable default guess. Note that overestimates tend to waste more
203
+ // space, while underestimates tend to waste more time.
204
+ #define PHMAP_CACHELINE_SIZE 64
205
+ #endif
206
+
207
+ #define PHMAP_CACHELINE_ALIGNED __attribute__((aligned(PHMAP_CACHELINE_SIZE)))
208
+ #elif defined(_MSC_VER)
209
+ #define PHMAP_CACHELINE_SIZE 64
210
+ #define PHMAP_CACHELINE_ALIGNED __declspec(align(PHMAP_CACHELINE_SIZE))
211
+ #else
212
+ #define PHMAP_CACHELINE_SIZE 64
213
+ #define PHMAP_CACHELINE_ALIGNED
214
+ #endif
215
+
216
+
217
+ #if PHMAP_HAVE_BUILTIN(__builtin_expect) || \
218
+ (defined(__GNUC__) && !defined(__clang__))
219
+ #define PHMAP_PREDICT_FALSE(x) (__builtin_expect(x, 0))
220
+ #define PHMAP_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
221
+ #else
222
+ #define PHMAP_PREDICT_FALSE(x) (x)
223
+ #define PHMAP_PREDICT_TRUE(x) (x)
224
+ #endif
225
+
226
+ // -----------------------------------------------------------------------------
227
+ // File: bits.h
228
+ // -----------------------------------------------------------------------------
229
+
230
+ #if defined(_MSC_VER)
231
+ // We can achieve something similar to attribute((always_inline)) with MSVC by
232
+ // using the __forceinline keyword, however this is not perfect. MSVC is
233
+ // much less aggressive about inlining, and even with the __forceinline keyword.
234
+ #define PHMAP_BASE_INTERNAL_FORCEINLINE __forceinline
235
+ #else
236
+ // Use default attribute inline.
237
+ #define PHMAP_BASE_INTERNAL_FORCEINLINE inline PHMAP_ATTRIBUTE_ALWAYS_INLINE
238
+ #endif
239
+
240
+
241
+ namespace phmap {
242
+
243
+ #if defined(__GNUC__)
244
+ #pragma GCC diagnostic push
245
+ #pragma GCC diagnostic ignored "-Wpedantic"
246
+ #endif
247
+
248
+ #ifdef PHMAP_HAVE_INTRINSIC_INT128
249
+ __extension__ typedef unsigned __int128 phmap_uint128;
250
+ inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high)
251
+ {
252
+ auto result = static_cast<phmap_uint128>(a) * static_cast<phmap_uint128>(b);
253
+ *high = static_cast<uint64_t>(result >> 64);
254
+ return static_cast<uint64_t>(result);
255
+ }
256
+ #define PHMAP_HAS_UMUL128 1
257
+ #elif (defined(_MSC_VER))
258
+ #if defined(_M_X64)
259
+ #pragma intrinsic(_umul128)
260
+ inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high)
261
+ {
262
+ return _umul128(a, b, high);
263
+ }
264
+ #define PHMAP_HAS_UMUL128 1
265
+ #endif
266
+ #endif
267
+
268
+ #if defined(__GNUC__)
269
+ #pragma GCC diagnostic pop
270
+ #endif
271
+
272
+ namespace base_internal {
273
+
274
+ PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountLeadingZeros64Slow(uint64_t n) {
275
+ int zeroes = 60;
276
+ if (n >> 32) zeroes -= 32, n >>= 32;
277
+ if (n >> 16) zeroes -= 16, n >>= 16;
278
+ if (n >> 8) zeroes -= 8, n >>= 8;
279
+ if (n >> 4) zeroes -= 4, n >>= 4;
280
+ return (uint32_t)("\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes);
281
+ }
282
+
283
+ PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountLeadingZeros64(uint64_t n) {
284
+ #if defined(_MSC_VER) && defined(_M_X64)
285
+ // MSVC does not have __buitin_clzll. Use _BitScanReverse64.
286
+ unsigned long result = 0; // NOLINT(runtime/int)
287
+ if (_BitScanReverse64(&result, n)) {
288
+ return (uint32_t)(63 - result);
289
+ }
290
+ return 64;
291
+ #elif defined(_MSC_VER) && !defined(__clang__)
292
+ // MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse
293
+ unsigned long result = 0; // NOLINT(runtime/int)
294
+ if ((n >> 32) && _BitScanReverse(&result, (unsigned long)(n >> 32))) {
295
+ return (uint32_t)(31 - result);
296
+ }
297
+ if (_BitScanReverse(&result, (unsigned long)n)) {
298
+ return (uint32_t)(63 - result);
299
+ }
300
+ return 64;
301
+ #elif defined(__GNUC__) || defined(__clang__)
302
+ // Use __builtin_clzll, which uses the following instructions:
303
+ // x86: bsr
304
+ // ARM64: clz
305
+ // PPC: cntlzd
306
+ static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
307
+ "__builtin_clzll does not take 64-bit arg");
308
+
309
+ // Handle 0 as a special case because __builtin_clzll(0) is undefined.
310
+ if (n == 0) {
311
+ return 64;
312
+ }
313
+ return (uint32_t)__builtin_clzll(n);
314
+ #else
315
+ return CountLeadingZeros64Slow(n);
316
+ #endif
317
+ }
318
+
319
+ PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountLeadingZeros32Slow(uint64_t n) {
320
+ uint32_t zeroes = 28;
321
+ if (n >> 16) zeroes -= 16, n >>= 16;
322
+ if (n >> 8) zeroes -= 8, n >>= 8;
323
+ if (n >> 4) zeroes -= 4, n >>= 4;
324
+ return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
325
+ }
326
+
327
+ PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountLeadingZeros32(uint32_t n) {
328
+ #if defined(_MSC_VER) && !defined(__clang__)
329
+ unsigned long result = 0; // NOLINT(runtime/int)
330
+ if (_BitScanReverse(&result, n)) {
331
+ return (uint32_t)(31 - result);
332
+ }
333
+ return 32;
334
+ #elif defined(__GNUC__) || defined(__clang__)
335
+ // Use __builtin_clz, which uses the following instructions:
336
+ // x86: bsr
337
+ // ARM64: clz
338
+ // PPC: cntlzd
339
+ static_assert(sizeof(int) == sizeof(n),
340
+ "__builtin_clz does not take 32-bit arg");
341
+
342
+ // Handle 0 as a special case because __builtin_clz(0) is undefined.
343
+ if (n == 0) {
344
+ return 32;
345
+ }
346
+ return __builtin_clz(n);
347
+ #else
348
+ return CountLeadingZeros32Slow(n);
349
+ #endif
350
+ }
351
+
352
+ PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountTrailingZerosNonZero64Slow(uint64_t n) {
353
+ uint32_t c = 63;
354
+ n &= ~n + 1;
355
+ if (n & 0x00000000FFFFFFFF) c -= 32;
356
+ if (n & 0x0000FFFF0000FFFF) c -= 16;
357
+ if (n & 0x00FF00FF00FF00FF) c -= 8;
358
+ if (n & 0x0F0F0F0F0F0F0F0F) c -= 4;
359
+ if (n & 0x3333333333333333) c -= 2;
360
+ if (n & 0x5555555555555555) c -= 1;
361
+ return c;
362
+ }
363
+
364
+ PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountTrailingZerosNonZero64(uint64_t n) {
365
+ #if defined(_MSC_VER) && !defined(__clang__) && defined(_M_X64)
366
+ unsigned long result = 0; // NOLINT(runtime/int)
367
+ _BitScanForward64(&result, n);
368
+ return (uint32_t)result;
369
+ #elif defined(_MSC_VER) && !defined(__clang__)
370
+ unsigned long result = 0; // NOLINT(runtime/int)
371
+ if (static_cast<uint32_t>(n) == 0) {
372
+ _BitScanForward(&result, (unsigned long)(n >> 32));
373
+ return result + 32;
374
+ }
375
+ _BitScanForward(&result, (unsigned long)n);
376
+ return result;
377
+ #elif defined(__GNUC__) || defined(__clang__)
378
+ static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
379
+ "__builtin_ctzll does not take 64-bit arg");
380
+ return __builtin_ctzll(n);
381
+ #else
382
+ return CountTrailingZerosNonZero64Slow(n);
383
+ #endif
384
+ }
385
+
386
+ PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountTrailingZerosNonZero32Slow(uint32_t n) {
387
+ uint32_t c = 31;
388
+ n &= ~n + 1;
389
+ if (n & 0x0000FFFF) c -= 16;
390
+ if (n & 0x00FF00FF) c -= 8;
391
+ if (n & 0x0F0F0F0F) c -= 4;
392
+ if (n & 0x33333333) c -= 2;
393
+ if (n & 0x55555555) c -= 1;
394
+ return c;
395
+ }
396
+
397
+ PHMAP_BASE_INTERNAL_FORCEINLINE uint32_t CountTrailingZerosNonZero32(uint32_t n) {
398
+ #if defined(_MSC_VER) && !defined(__clang__)
399
+ unsigned long result = 0; // NOLINT(runtime/int)
400
+ _BitScanForward(&result, n);
401
+ return (uint32_t)result;
402
+ #elif defined(__GNUC__) || defined(__clang__)
403
+ static_assert(sizeof(int) == sizeof(n),
404
+ "__builtin_ctz does not take 32-bit arg");
405
+ return __builtin_ctz(n);
406
+ #else
407
+ return CountTrailingZerosNonZero32Slow(n);
408
+ #endif
409
+ }
410
+
411
+ #undef PHMAP_BASE_INTERNAL_FORCEINLINE
412
+
413
+ } // namespace base_internal
414
+ } // namespace phmap
415
+
416
+ // -----------------------------------------------------------------------------
417
+ // File: endian.h
418
+ // -----------------------------------------------------------------------------
419
+
420
+ namespace phmap {
421
+
422
+ // Use compiler byte-swapping intrinsics if they are available. 32-bit
423
+ // and 64-bit versions are available in Clang and GCC as of GCC 4.3.0.
424
+ // The 16-bit version is available in Clang and GCC only as of GCC 4.8.0.
425
+ // For simplicity, we enable them all only for GCC 4.8.0 or later.
426
+ #if defined(__clang__) || \
427
+ (defined(__GNUC__) && \
428
+ ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5))
429
+
430
+ inline uint64_t gbswap_64(uint64_t host_int) {
431
+ return __builtin_bswap64(host_int);
432
+ }
433
+ inline uint32_t gbswap_32(uint32_t host_int) {
434
+ return __builtin_bswap32(host_int);
435
+ }
436
+ inline uint16_t gbswap_16(uint16_t host_int) {
437
+ return __builtin_bswap16(host_int);
438
+ }
439
+
440
+ #elif defined(_MSC_VER)
441
+
442
+ inline uint64_t gbswap_64(uint64_t host_int) {
443
+ return _byteswap_uint64(host_int);
444
+ }
445
+ inline uint32_t gbswap_32(uint32_t host_int) {
446
+ return _byteswap_ulong(host_int);
447
+ }
448
+ inline uint16_t gbswap_16(uint16_t host_int) {
449
+ return _byteswap_ushort(host_int);
450
+ }
451
+
452
+ #elif defined(__APPLE__)
453
+
454
+ inline uint64_t gbswap_64(uint64_t host_int) { return OSSwapInt16(host_int); }
455
+ inline uint32_t gbswap_32(uint32_t host_int) { return OSSwapInt32(host_int); }
456
+ inline uint16_t gbswap_16(uint16_t host_int) { return OSSwapInt64(host_int); }
457
+
458
+ #else
459
+
460
+ inline uint64_t gbswap_64(uint64_t host_int) {
461
+ #if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__)
462
+ // Adapted from /usr/include/byteswap.h. Not available on Mac.
463
+ if (__builtin_constant_p(host_int)) {
464
+ return __bswap_constant_64(host_int);
465
+ } else {
466
+ uint64_t result;
467
+ __asm__("bswap %0" : "=r"(result) : "0"(host_int));
468
+ return result;
469
+ }
470
+ #elif defined(__GLIBC__)
471
+ return bswap_64(host_int);
472
+ #else
473
+ return (((host_int & uint64_t{0xFF}) << 56) |
474
+ ((host_int & uint64_t{0xFF00}) << 40) |
475
+ ((host_int & uint64_t{0xFF0000}) << 24) |
476
+ ((host_int & uint64_t{0xFF000000}) << 8) |
477
+ ((host_int & uint64_t{0xFF00000000}) >> 8) |
478
+ ((host_int & uint64_t{0xFF0000000000}) >> 24) |
479
+ ((host_int & uint64_t{0xFF000000000000}) >> 40) |
480
+ ((host_int & uint64_t{0xFF00000000000000}) >> 56));
481
+ #endif // bswap_64
482
+ }
483
+
484
+ inline uint32_t gbswap_32(uint32_t host_int) {
485
+ #if defined(__GLIBC__)
486
+ return bswap_32(host_int);
487
+ #else
488
+ return (((host_int & uint32_t{0xFF}) << 24) |
489
+ ((host_int & uint32_t{0xFF00}) << 8) |
490
+ ((host_int & uint32_t{0xFF0000}) >> 8) |
491
+ ((host_int & uint32_t{0xFF000000}) >> 24));
492
+ #endif
493
+ }
494
+
495
+ inline uint16_t gbswap_16(uint16_t host_int) {
496
+ #if defined(__GLIBC__)
497
+ return bswap_16(host_int);
498
+ #else
499
+ return (((host_int & uint16_t{0xFF}) << 8) |
500
+ ((host_int & uint16_t{0xFF00}) >> 8));
501
+ #endif
502
+ }
503
+
504
+ #endif // intrinics available
505
+
506
+ #ifdef PHMAP_IS_LITTLE_ENDIAN
507
+
508
+ // Definitions for ntohl etc. that don't require us to include
509
+ // netinet/in.h. We wrap gbswap_32 and gbswap_16 in functions rather
510
+ // than just #defining them because in debug mode, gcc doesn't
511
+ // correctly handle the (rather involved) definitions of bswap_32.
512
+ // gcc guarantees that inline functions are as fast as macros, so
513
+ // this isn't a performance hit.
514
+ inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); }
515
+ inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); }
516
+ inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); }
517
+
518
+ #elif defined PHMAP_IS_BIG_ENDIAN
519
+
520
+ // These definitions are simpler on big-endian machines
521
+ // These are functions instead of macros to avoid self-assignment warnings
522
+ // on calls such as "i = ghtnol(i);". This also provides type checking.
523
+ inline uint16_t ghtons(uint16_t x) { return x; }
524
+ inline uint32_t ghtonl(uint32_t x) { return x; }
525
+ inline uint64_t ghtonll(uint64_t x) { return x; }
526
+
527
+ #else
528
+ #error \
529
+ "Unsupported byte order: Either PHMAP_IS_BIG_ENDIAN or " \
530
+ "PHMAP_IS_LITTLE_ENDIAN must be defined"
531
+ #endif // byte order
532
+
533
+ inline uint16_t gntohs(uint16_t x) { return ghtons(x); }
534
+ inline uint32_t gntohl(uint32_t x) { return ghtonl(x); }
535
+ inline uint64_t gntohll(uint64_t x) { return ghtonll(x); }
536
+
537
+ // Utilities to convert numbers between the current hosts's native byte
538
+ // order and little-endian byte order
539
+ //
540
+ // Load/Store methods are alignment safe
541
+ namespace little_endian {
542
+ // Conversion functions.
543
+ #ifdef PHMAP_IS_LITTLE_ENDIAN
544
+
545
+ inline uint16_t FromHost16(uint16_t x) { return x; }
546
+ inline uint16_t ToHost16(uint16_t x) { return x; }
547
+
548
+ inline uint32_t FromHost32(uint32_t x) { return x; }
549
+ inline uint32_t ToHost32(uint32_t x) { return x; }
550
+
551
+ inline uint64_t FromHost64(uint64_t x) { return x; }
552
+ inline uint64_t ToHost64(uint64_t x) { return x; }
553
+
554
+ inline constexpr bool IsLittleEndian() { return true; }
555
+
556
+ #elif defined PHMAP_IS_BIG_ENDIAN
557
+
558
+ inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); }
559
+ inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); }
560
+
561
+ inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); }
562
+ inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); }
563
+
564
+ inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
565
+ inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }
566
+
567
+ inline constexpr bool IsLittleEndian() { return false; }
568
+
569
+ #endif /* ENDIAN */
570
+
571
+ // Functions to do unaligned loads and stores in little-endian order.
572
+ // ------------------------------------------------------------------
573
+ inline uint16_t Load16(const void *p) {
574
+ return ToHost16(PHMAP_INTERNAL_UNALIGNED_LOAD16(p));
575
+ }
576
+
577
+ inline void Store16(void *p, uint16_t v) {
578
+ PHMAP_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
579
+ }
580
+
581
+ inline uint32_t Load32(const void *p) {
582
+ return ToHost32(PHMAP_INTERNAL_UNALIGNED_LOAD32(p));
583
+ }
584
+
585
+ inline void Store32(void *p, uint32_t v) {
586
+ PHMAP_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
587
+ }
588
+
589
+ inline uint64_t Load64(const void *p) {
590
+ return ToHost64(PHMAP_INTERNAL_UNALIGNED_LOAD64(p));
591
+ }
592
+
593
+ inline void Store64(void *p, uint64_t v) {
594
+ PHMAP_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
595
+ }
596
+
597
+ } // namespace little_endian
598
+
599
+ // Utilities to convert numbers between the current hosts's native byte
600
+ // order and big-endian byte order (same as network byte order)
601
+ //
602
+ // Load/Store methods are alignment safe
603
+ namespace big_endian {
604
+ #ifdef PHMAP_IS_LITTLE_ENDIAN
605
+
606
+ inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); }
607
+ inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); }
608
+
609
+ inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); }
610
+ inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); }
611
+
612
+ inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); }
613
+ inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); }
614
+
615
+ inline constexpr bool IsLittleEndian() { return true; }
616
+
617
+ #elif defined PHMAP_IS_BIG_ENDIAN
618
+
619
+ inline uint16_t FromHost16(uint16_t x) { return x; }
620
+ inline uint16_t ToHost16(uint16_t x) { return x; }
621
+
622
+ inline uint32_t FromHost32(uint32_t x) { return x; }
623
+ inline uint32_t ToHost32(uint32_t x) { return x; }
624
+
625
+ inline uint64_t FromHost64(uint64_t x) { return x; }
626
+ inline uint64_t ToHost64(uint64_t x) { return x; }
627
+
628
+ inline constexpr bool IsLittleEndian() { return false; }
629
+
630
+ #endif /* ENDIAN */
631
+
632
+ // Functions to do unaligned loads and stores in big-endian order.
633
+ inline uint16_t Load16(const void *p) {
634
+ return ToHost16(PHMAP_INTERNAL_UNALIGNED_LOAD16(p));
635
+ }
636
+
637
+ inline void Store16(void *p, uint16_t v) {
638
+ PHMAP_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
639
+ }
640
+
641
+ inline uint32_t Load32(const void *p) {
642
+ return ToHost32(PHMAP_INTERNAL_UNALIGNED_LOAD32(p));
643
+ }
644
+
645
+ inline void Store32(void *p, uint32_t v) {
646
+ PHMAP_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
647
+ }
648
+
649
+ inline uint64_t Load64(const void *p) {
650
+ return ToHost64(PHMAP_INTERNAL_UNALIGNED_LOAD64(p));
651
+ }
652
+
653
+ inline void Store64(void *p, uint64_t v) {
654
+ PHMAP_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
655
+ }
656
+
657
+ } // namespace big_endian
658
+
659
+ } // namespace phmap
660
+
661
+ #ifdef _MSC_VER
662
+ #pragma warning(pop)
663
+ #endif
664
+
665
+ #endif // phmap_bits_h_guard_