usearch 0.9.3 → 0.9.4

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.
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "usearch"
3
- version = "0.9.3"
3
+ version = "0.9.4"
4
4
  authors = ["Ashot Vardanian <1983160+ashvardanian@users.noreply.github.com>"]
5
5
  description = "Smaller & Faster Single-File Vector Search Engine from Unum"
6
6
  edition = "2021"
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.3
1
+ 0.9.4
package/conanfile.py CHANGED
@@ -4,7 +4,7 @@ from conans import ConanFile
4
4
  class USearchConan(ConanFile):
5
5
 
6
6
  name = 'USearch'
7
- version = '0.9.3'
7
+ version = '0.9.4'
8
8
  license = 'Apache 2.0'
9
9
  url = 'https://github.com/unum-cloud/usearch'
10
10
  description = 'Smaller & Faster Single-File Vector Search Engine from Unum'
@@ -410,71 +410,75 @@ template <typename allocator_at = std::allocator<char>> class visits_bitset_gt {
410
410
 
411
411
  #if defined(USEARCH_IS_WINDOWS)
412
412
  using slot_t = LONG volatile;
413
- static_assert(sizeof(slot_t) == 8);
414
413
  #else
415
414
  using slot_t = std::uint64_t;
416
415
  #endif
417
416
 
418
- std::uint64_t* u64s_{};
419
- std::size_t slots_{};
417
+ static constexpr std::size_t bits_per_slot() { return sizeof(slot_t) * CHAR_BIT; }
418
+ static constexpr slot_t bits_mask() { return sizeof(slot_t) * CHAR_BIT - 1; }
419
+
420
+ slot_t* slots_{};
421
+ std::size_t slots_count_{};
420
422
 
421
423
  public:
422
424
  visits_bitset_gt() noexcept {}
423
425
  visits_bitset_gt(std::size_t capacity) noexcept {
424
- slots_ = divide_round_up<64>(capacity);
425
- u64s_ = (slot_t*)allocator_t{}.allocate(slots_ * sizeof(slot_t));
426
+ slots_count_ = divide_round_up<bits_per_slot()>(capacity);
427
+ slots_ = (slot_t*)allocator_t{}.allocate(slots_count_ * sizeof(slot_t));
426
428
  clear();
427
429
  }
428
- ~visits_bitset_gt() noexcept { allocator_t{}.deallocate((byte_t*)u64s_, slots_ * sizeof(slot_t)), u64s_ = nullptr; }
429
- void clear() noexcept { std::memset(u64s_, 0, slots_ * sizeof(slot_t)); }
430
- inline bool test(std::size_t i) const noexcept { return u64s_[i / 64] & (1ul << (i & 63ul)); }
431
- inline void set(std::size_t i) noexcept { u64s_[i / 64] |= (1ul << (i & 63ul)); }
430
+ ~visits_bitset_gt() noexcept {
431
+ allocator_t{}.deallocate((byte_t*)slots_, slots_count_ * sizeof(slot_t)), slots_ = nullptr;
432
+ }
433
+ void clear() noexcept { std::memset(slots_, 0, slots_count_ * sizeof(slot_t)); }
434
+ inline bool test(std::size_t i) const noexcept { return slots_[i / bits_per_slot()] & (1ul << (i & bits_mask())); }
435
+ inline void set(std::size_t i) noexcept { slots_[i / bits_per_slot()] |= (1ul << (i & bits_mask())); }
432
436
 
433
437
  visits_bitset_gt(visits_bitset_gt&& other) noexcept {
434
- u64s_ = other.u64s_;
435
438
  slots_ = other.slots_;
436
- other.u64s_ = nullptr;
437
- other.slots_ = 0;
439
+ slots_count_ = other.slots_count_;
440
+ other.slots_ = nullptr;
441
+ other.slots_count_ = 0;
438
442
  }
439
443
 
440
444
  visits_bitset_gt& operator=(visits_bitset_gt&& other) noexcept {
441
- std::swap(u64s_, other.u64s_);
442
445
  std::swap(slots_, other.slots_);
446
+ std::swap(slots_count_, other.slots_count_);
443
447
  return *this;
444
448
  }
445
449
 
446
450
  #if defined(USEARCH_IS_WINDOWS)
447
451
 
448
452
  inline bool atomic_test(std::size_t i) noexcept {
449
- slot_t mask{1ul << (i & 63ul)};
450
- return InterlockedOr(&u64s_[i / 64], 0) & mask;
453
+ slot_t mask{1ul << (i & bits_mask())};
454
+ return InterlockedOr(&slots_[i / bits_per_slot()], 0) & mask;
451
455
  }
452
456
 
453
457
  inline bool atomic_set(std::size_t i) noexcept {
454
- slot_t mask{1ul << (i & 63ul)};
455
- return InterLockedOr(&u64s_[i / 64], mask) & mask;
458
+ slot_t mask{1ul << (i & bits_mask())};
459
+ return InterLockedOr(&slots_[i / bits_per_slot()], mask) & mask;
456
460
  }
457
461
 
458
462
  inline void atomic_reset(std::size_t i) noexcept {
459
- slot_t mask{1ul << (i & 63ul)};
460
- InterLockedAnd((LONG volatile*)&u64s_[i / 64], ~mask);
463
+ slot_t mask{1ul << (i & bits_mask())};
464
+ InterLockedAnd((LONG volatile*)&slots_[i / bits_per_slot()], ~mask);
461
465
  }
462
466
 
463
467
  #else
464
468
 
465
469
  inline bool atomic_test(std::size_t i) noexcept {
466
- slot_t mask{1ul << (i & 63ul)};
467
- return __atomic_load_n(&u64s_[i / 64], __ATOMIC_RELAXED) & mask;
470
+ slot_t mask{1ul << (i & bits_mask())};
471
+ return __atomic_load_n(&slots_[i / bits_per_slot()], __ATOMIC_RELAXED) & mask;
468
472
  }
469
473
 
470
474
  inline bool atomic_set(std::size_t i) noexcept {
471
- slot_t mask{1ul << (i & 63ul)};
472
- return __atomic_fetch_or(&u64s_[i / 64], mask, __ATOMIC_ACQUIRE) & mask;
475
+ slot_t mask{1ul << (i & bits_mask())};
476
+ return __atomic_fetch_or(&slots_[i / bits_per_slot()], mask, __ATOMIC_ACQUIRE) & mask;
473
477
  }
474
478
 
475
479
  inline void atomic_reset(std::size_t i) noexcept {
476
- slot_t mask{1ul << (i & 63ul)};
477
- __atomic_fetch_and(&u64s_[i / 64], ~mask, __ATOMIC_RELEASE);
480
+ slot_t mask{1ul << (i & bits_mask())};
481
+ __atomic_fetch_and(&slots_[i / bits_per_slot()], ~mask, __ATOMIC_RELEASE);
478
482
  }
479
483
 
480
484
  #endif
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usearch",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "description": "Smaller & Faster Single-File Vector Search Engine from Unum",
5
5
  "author": "Ashot Vardanian",
6
6
  "license": "Apache 2.0",
package/pyproject.toml CHANGED
@@ -46,3 +46,4 @@ before-build = [
46
46
  "git submodule update --init --recursive"
47
47
  ]
48
48
  archs = ["x86", "AMD64"]
49
+ skip = ["*win32*"]