hnswlib 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/hnswlib/src/bruteforce.h +2 -2
- data/ext/hnswlib/src/hnswalg.h +51 -38
- data/ext/hnswlib/src/hnswlib.h +9 -0
- data/ext/hnswlib/src/space_ip.h +36 -3
- data/ext/hnswlib/src/space_l2.h +38 -4
- data/ext/hnswlib/src/visited_list_pool.h +1 -0
- data/lib/hnswlib/version.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec8d1a750f703968418f3aca9beffc33c061c9c5e7e6d24050a8aa8cd15e0d35
|
4
|
+
data.tar.gz: e8bb3c9b706dfd6d6d25d5f471970b50a6f191efbe9719437d0ce00c0c7a1420
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f39ec12aac12a0af0a4882f092c61b29417d14c575580b821ccb2154568e9c04e6a4170617cfa0185ca32dc322181cd18dd116bd527fc3f61b52cee3180b648
|
7
|
+
data.tar.gz: e355334afba1ed2f8817e2dda8eedd4bc61670f08ea349e44b7259c01584a195e2bb33f3de9f2f5d4ce59cd6cb80bd17b7f0c3b5e5dedd26dd0d8880c75d25ad
|
data/CHANGELOG.md
CHANGED
@@ -92,13 +92,13 @@ namespace hnswlib {
|
|
92
92
|
searchKnn(const void *query_data, size_t k) const {
|
93
93
|
std::priority_queue<std::pair<dist_t, labeltype >> topResults;
|
94
94
|
if (cur_element_count == 0) return topResults;
|
95
|
-
for (
|
95
|
+
for (int i = 0; i < k; i++) {
|
96
96
|
dist_t dist = fstdistfunc_(query_data, data_ + size_per_element_ * i, dist_func_param_);
|
97
97
|
topResults.push(std::pair<dist_t, labeltype>(dist, *((labeltype *) (data_ + size_per_element_ * i +
|
98
98
|
data_size_))));
|
99
99
|
}
|
100
100
|
dist_t lastdist = topResults.top().first;
|
101
|
-
for (
|
101
|
+
for (int i = k; i < cur_element_count; i++) {
|
102
102
|
dist_t dist = fstdistfunc_(query_data, data_ + size_per_element_ * i, dist_func_param_);
|
103
103
|
if (dist <= lastdist) {
|
104
104
|
topResults.push(std::pair<dist_t, labeltype>(dist, *((labeltype *) (data_ + size_per_element_ * i +
|
data/ext/hnswlib/src/hnswalg.h
CHANGED
@@ -19,7 +19,6 @@ namespace hnswlib {
|
|
19
19
|
static const tableint max_update_element_locks = 65536;
|
20
20
|
HierarchicalNSW() : visited_list_pool_(nullptr), data_level0_memory_(nullptr), linkLists_(nullptr), cur_element_count(0) { }
|
21
21
|
HierarchicalNSW(SpaceInterface<dist_t> *s) {
|
22
|
-
|
23
22
|
}
|
24
23
|
|
25
24
|
HierarchicalNSW(SpaceInterface<dist_t> *s, const std::string &location, bool nmslib = false, size_t max_elements=0) {
|
@@ -30,7 +29,7 @@ namespace hnswlib {
|
|
30
29
|
link_list_locks_(max_elements), link_list_update_locks_(max_update_element_locks), element_levels_(max_elements) {
|
31
30
|
max_elements_ = max_elements;
|
32
31
|
|
33
|
-
|
32
|
+
num_deleted_ = 0;
|
34
33
|
data_size_ = s->get_data_size();
|
35
34
|
fstdistfunc_ = s->get_dist_func();
|
36
35
|
dist_func_param_ = s->get_dist_func_param();
|
@@ -57,8 +56,6 @@ namespace hnswlib {
|
|
57
56
|
|
58
57
|
visited_list_pool_ = new VisitedListPool(1, max_elements);
|
59
58
|
|
60
|
-
|
61
|
-
|
62
59
|
//initializations for special treatment of the first node
|
63
60
|
enterpoint_node_ = -1;
|
64
61
|
maxlevel_ = -1;
|
@@ -93,6 +90,7 @@ namespace hnswlib {
|
|
93
90
|
size_t cur_element_count;
|
94
91
|
size_t size_data_per_element_;
|
95
92
|
size_t size_links_per_element_;
|
93
|
+
size_t num_deleted_;
|
96
94
|
|
97
95
|
size_t M_;
|
98
96
|
size_t maxM_;
|
@@ -113,20 +111,15 @@ namespace hnswlib {
|
|
113
111
|
std::vector<std::mutex> link_list_update_locks_;
|
114
112
|
tableint enterpoint_node_;
|
115
113
|
|
116
|
-
|
117
114
|
size_t size_links_level0_;
|
118
115
|
size_t offsetData_, offsetLevel0_;
|
119
116
|
|
120
|
-
|
121
117
|
char *data_level0_memory_;
|
122
118
|
char **linkLists_;
|
123
119
|
std::vector<int> element_levels_;
|
124
120
|
|
125
121
|
size_t data_size_;
|
126
122
|
|
127
|
-
bool has_deletions_;
|
128
|
-
|
129
|
-
|
130
123
|
size_t label_offset_;
|
131
124
|
DISTFUNC<dist_t> fstdistfunc_;
|
132
125
|
void *dist_func_param_;
|
@@ -183,7 +176,7 @@ namespace hnswlib {
|
|
183
176
|
|
184
177
|
while (!candidateSet.empty()) {
|
185
178
|
std::pair<dist_t, tableint> curr_el_pair = candidateSet.top();
|
186
|
-
if ((-curr_el_pair.first) > lowerBound) {
|
179
|
+
if ((-curr_el_pair.first) > lowerBound && top_candidates.size() == ef_construction_) {
|
187
180
|
break;
|
188
181
|
}
|
189
182
|
candidateSet.pop();
|
@@ -272,7 +265,7 @@ namespace hnswlib {
|
|
272
265
|
|
273
266
|
std::pair<dist_t, tableint> current_node_pair = candidate_set.top();
|
274
267
|
|
275
|
-
if ((-current_node_pair.first) > lowerBound) {
|
268
|
+
if ((-current_node_pair.first) > lowerBound && (top_candidates.size() == ef || has_deletions == false)) {
|
276
269
|
break;
|
277
270
|
}
|
278
271
|
candidate_set.pop();
|
@@ -548,7 +541,7 @@ namespace hnswlib {
|
|
548
541
|
}
|
549
542
|
}
|
550
543
|
|
551
|
-
if (
|
544
|
+
if (num_deleted_) {
|
552
545
|
std::priority_queue<std::pair<dist_t, tableint >> top_candidates1=searchBaseLayerST<true>(currObj, query_data,
|
553
546
|
ef_);
|
554
547
|
top_candidates.swap(top_candidates1);
|
@@ -624,8 +617,6 @@ namespace hnswlib {
|
|
624
617
|
}
|
625
618
|
|
626
619
|
void loadIndex(const std::string &location, SpaceInterface<dist_t> *s, size_t max_elements_i=0) {
|
627
|
-
|
628
|
-
|
629
620
|
std::ifstream input(location, std::ios::binary);
|
630
621
|
|
631
622
|
if (!input.is_open())
|
@@ -640,7 +631,7 @@ namespace hnswlib {
|
|
640
631
|
readBinaryPOD(input, max_elements_);
|
641
632
|
readBinaryPOD(input, cur_element_count);
|
642
633
|
|
643
|
-
size_t max_elements=max_elements_i;
|
634
|
+
size_t max_elements = max_elements_i;
|
644
635
|
if(max_elements < cur_element_count)
|
645
636
|
max_elements = max_elements_;
|
646
637
|
max_elements_ = max_elements;
|
@@ -689,26 +680,19 @@ namespace hnswlib {
|
|
689
680
|
|
690
681
|
input.seekg(pos,input.beg);
|
691
682
|
|
692
|
-
|
693
683
|
data_level0_memory_ = (char *) malloc(max_elements * size_data_per_element_);
|
694
684
|
if (data_level0_memory_ == nullptr)
|
695
685
|
throw std::runtime_error("Not enough memory: loadIndex failed to allocate level0");
|
696
686
|
input.read(data_level0_memory_, cur_element_count * size_data_per_element_);
|
697
687
|
|
698
|
-
|
699
|
-
|
700
|
-
|
701
688
|
size_links_per_element_ = maxM_ * sizeof(tableint) + sizeof(linklistsizeint);
|
702
689
|
|
703
|
-
|
704
690
|
size_links_level0_ = maxM0_ * sizeof(tableint) + sizeof(linklistsizeint);
|
705
691
|
std::vector<std::mutex>(max_elements).swap(link_list_locks_);
|
706
692
|
std::vector<std::mutex>(max_update_element_locks).swap(link_list_update_locks_);
|
707
693
|
|
708
|
-
|
709
694
|
visited_list_pool_ = new VisitedListPool(1, max_elements);
|
710
695
|
|
711
|
-
|
712
696
|
linkLists_ = (char **) malloc(sizeof(void *) * max_elements);
|
713
697
|
if (linkLists_ == nullptr)
|
714
698
|
throw std::runtime_error("Not enough memory: loadIndex failed to allocate linklists");
|
@@ -732,11 +716,9 @@ namespace hnswlib {
|
|
732
716
|
}
|
733
717
|
}
|
734
718
|
|
735
|
-
has_deletions_=false;
|
736
|
-
|
737
719
|
for (size_t i = 0; i < cur_element_count; i++) {
|
738
720
|
if(isMarkedDeleted(i))
|
739
|
-
|
721
|
+
num_deleted_ += 1;
|
740
722
|
}
|
741
723
|
|
742
724
|
input.close();
|
@@ -745,7 +727,7 @@ namespace hnswlib {
|
|
745
727
|
}
|
746
728
|
|
747
729
|
template<typename data_t>
|
748
|
-
std::vector<data_t> getDataByLabel(labeltype label)
|
730
|
+
std::vector<data_t> getDataByLabel(labeltype label) const
|
749
731
|
{
|
750
732
|
tableint label_c;
|
751
733
|
auto search = label_lookup_.find(label);
|
@@ -758,7 +740,7 @@ namespace hnswlib {
|
|
758
740
|
size_t dim = *((size_t *) dist_func_param_);
|
759
741
|
std::vector<data_t> data;
|
760
742
|
data_t* data_ptr = (data_t*) data_ptrv;
|
761
|
-
for (
|
743
|
+
for (int i = 0; i < dim; i++) {
|
762
744
|
data.push_back(*data_ptr);
|
763
745
|
data_ptr += 1;
|
764
746
|
}
|
@@ -766,19 +748,19 @@ namespace hnswlib {
|
|
766
748
|
}
|
767
749
|
|
768
750
|
static const unsigned char DELETE_MARK = 0x01;
|
769
|
-
//
|
751
|
+
// static const unsigned char REUSE_MARK = 0x10;
|
770
752
|
/**
|
771
753
|
* Marks an element with the given label deleted, does NOT really change the current graph.
|
772
754
|
* @param label
|
773
755
|
*/
|
774
756
|
void markDelete(labeltype label)
|
775
757
|
{
|
776
|
-
has_deletions_=true;
|
777
758
|
auto search = label_lookup_.find(label);
|
778
759
|
if (search == label_lookup_.end()) {
|
779
760
|
throw std::runtime_error("Label not found");
|
780
761
|
}
|
781
|
-
|
762
|
+
tableint internalId = search->second;
|
763
|
+
markDeletedInternal(internalId);
|
782
764
|
}
|
783
765
|
|
784
766
|
/**
|
@@ -787,8 +769,31 @@ namespace hnswlib {
|
|
787
769
|
* @param internalId
|
788
770
|
*/
|
789
771
|
void markDeletedInternal(tableint internalId) {
|
790
|
-
|
791
|
-
|
772
|
+
assert(internalId < cur_element_count);
|
773
|
+
if (!isMarkedDeleted(internalId))
|
774
|
+
{
|
775
|
+
unsigned char *ll_cur = ((unsigned char *)get_linklist0(internalId))+2;
|
776
|
+
*ll_cur |= DELETE_MARK;
|
777
|
+
num_deleted_ += 1;
|
778
|
+
}
|
779
|
+
else
|
780
|
+
{
|
781
|
+
throw std::runtime_error("The requested to delete element is already deleted");
|
782
|
+
}
|
783
|
+
}
|
784
|
+
|
785
|
+
/**
|
786
|
+
* Remove the deleted mark of the node, does NOT really change the current graph.
|
787
|
+
* @param label
|
788
|
+
*/
|
789
|
+
void unmarkDelete(labeltype label)
|
790
|
+
{
|
791
|
+
auto search = label_lookup_.find(label);
|
792
|
+
if (search == label_lookup_.end()) {
|
793
|
+
throw std::runtime_error("Label not found");
|
794
|
+
}
|
795
|
+
tableint internalId = search->second;
|
796
|
+
unmarkDeletedInternal(internalId);
|
792
797
|
}
|
793
798
|
|
794
799
|
/**
|
@@ -796,8 +801,17 @@ namespace hnswlib {
|
|
796
801
|
* @param internalId
|
797
802
|
*/
|
798
803
|
void unmarkDeletedInternal(tableint internalId) {
|
799
|
-
|
800
|
-
|
804
|
+
assert(internalId < cur_element_count);
|
805
|
+
if (isMarkedDeleted(internalId))
|
806
|
+
{
|
807
|
+
unsigned char *ll_cur = ((unsigned char *)get_linklist0(internalId))+2;
|
808
|
+
*ll_cur &= ~DELETE_MARK;
|
809
|
+
num_deleted_ -= 1;
|
810
|
+
}
|
811
|
+
else
|
812
|
+
{
|
813
|
+
throw std::runtime_error("The requested to undelete element is not deleted");
|
814
|
+
}
|
801
815
|
}
|
802
816
|
|
803
817
|
/**
|
@@ -858,8 +872,8 @@ namespace hnswlib {
|
|
858
872
|
}
|
859
873
|
|
860
874
|
for (auto&& neigh : sNeigh) {
|
861
|
-
//
|
862
|
-
//
|
875
|
+
// if (neigh == internalId)
|
876
|
+
// continue;
|
863
877
|
|
864
878
|
std::priority_queue<std::pair<dist_t, tableint>, std::vector<std::pair<dist_t, tableint>>, CompareByFirst> candidates;
|
865
879
|
size_t size = sCand.find(neigh) == sCand.end() ? sCand.size() : sCand.size() - 1; // sCand guaranteed to have size >= 1
|
@@ -990,7 +1004,6 @@ namespace hnswlib {
|
|
990
1004
|
unmarkDeletedInternal(existingInternalId);
|
991
1005
|
}
|
992
1006
|
updatePoint(data_point, existingInternalId, 1.0);
|
993
|
-
|
994
1007
|
return existingInternalId;
|
995
1008
|
}
|
996
1009
|
|
@@ -1134,7 +1147,7 @@ namespace hnswlib {
|
|
1134
1147
|
}
|
1135
1148
|
|
1136
1149
|
std::priority_queue<std::pair<dist_t, tableint>, std::vector<std::pair<dist_t, tableint>>, CompareByFirst> top_candidates;
|
1137
|
-
if (
|
1150
|
+
if (num_deleted_) {
|
1138
1151
|
top_candidates=searchBaseLayerST<true,true>(
|
1139
1152
|
currObj, query_data, std::max(ef_, k));
|
1140
1153
|
}
|
data/ext/hnswlib/src/hnswlib.h
CHANGED
@@ -4,6 +4,9 @@
|
|
4
4
|
#define USE_SSE
|
5
5
|
#ifdef __AVX__
|
6
6
|
#define USE_AVX
|
7
|
+
#ifdef __AVX512F__
|
8
|
+
#define USE_AVX512
|
9
|
+
#endif
|
7
10
|
#endif
|
8
11
|
#endif
|
9
12
|
#endif
|
@@ -16,10 +19,16 @@
|
|
16
19
|
#include <x86intrin.h>
|
17
20
|
#endif
|
18
21
|
|
22
|
+
#if defined(USE_AVX512)
|
23
|
+
#include <immintrin.h>
|
24
|
+
#endif
|
25
|
+
|
19
26
|
#if defined(__GNUC__)
|
20
27
|
#define PORTABLE_ALIGN32 __attribute__((aligned(32)))
|
28
|
+
#define PORTABLE_ALIGN64 __attribute__((aligned(64)))
|
21
29
|
#else
|
22
30
|
#define PORTABLE_ALIGN32 __declspec(align(32))
|
31
|
+
#define PORTABLE_ALIGN64 __declspec(align(64))
|
23
32
|
#endif
|
24
33
|
#endif
|
25
34
|
|
data/ext/hnswlib/src/space_ip.h
CHANGED
@@ -124,7 +124,40 @@ namespace hnswlib {
|
|
124
124
|
|
125
125
|
#endif
|
126
126
|
|
127
|
-
|
127
|
+
|
128
|
+
#if defined(USE_AVX512)
|
129
|
+
|
130
|
+
static float
|
131
|
+
InnerProductSIMD16Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
|
132
|
+
float PORTABLE_ALIGN64 TmpRes[16];
|
133
|
+
float *pVect1 = (float *) pVect1v;
|
134
|
+
float *pVect2 = (float *) pVect2v;
|
135
|
+
size_t qty = *((size_t *) qty_ptr);
|
136
|
+
|
137
|
+
size_t qty16 = qty / 16;
|
138
|
+
|
139
|
+
|
140
|
+
const float *pEnd1 = pVect1 + 16 * qty16;
|
141
|
+
|
142
|
+
__m512 sum512 = _mm512_set1_ps(0);
|
143
|
+
|
144
|
+
while (pVect1 < pEnd1) {
|
145
|
+
//_mm_prefetch((char*)(pVect2 + 16), _MM_HINT_T0);
|
146
|
+
|
147
|
+
__m512 v1 = _mm512_loadu_ps(pVect1);
|
148
|
+
pVect1 += 16;
|
149
|
+
__m512 v2 = _mm512_loadu_ps(pVect2);
|
150
|
+
pVect2 += 16;
|
151
|
+
sum512 = _mm512_add_ps(sum512, _mm512_mul_ps(v1, v2));
|
152
|
+
}
|
153
|
+
|
154
|
+
_mm512_store_ps(TmpRes, sum512);
|
155
|
+
float sum = TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3] + TmpRes[4] + TmpRes[5] + TmpRes[6] + TmpRes[7] + TmpRes[8] + TmpRes[9] + TmpRes[10] + TmpRes[11] + TmpRes[12] + TmpRes[13] + TmpRes[14] + TmpRes[15];
|
156
|
+
|
157
|
+
return 1.0f - sum;
|
158
|
+
}
|
159
|
+
|
160
|
+
#elif defined(USE_AVX)
|
128
161
|
|
129
162
|
static float
|
130
163
|
InnerProductSIMD16Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
|
@@ -211,7 +244,7 @@ namespace hnswlib {
|
|
211
244
|
|
212
245
|
#endif
|
213
246
|
|
214
|
-
#if defined(USE_SSE) || defined(USE_AVX)
|
247
|
+
#if defined(USE_SSE) || defined(USE_AVX) || defined(USE_AVX512)
|
215
248
|
static float
|
216
249
|
InnerProductSIMD16ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
|
217
250
|
size_t qty = *((size_t *) qty_ptr);
|
@@ -250,7 +283,7 @@ namespace hnswlib {
|
|
250
283
|
InnerProductSpace() : data_size_(0), dim_(0) { }
|
251
284
|
InnerProductSpace(size_t dim) {
|
252
285
|
fstdistfunc_ = InnerProduct;
|
253
|
-
#if defined(USE_AVX) || defined(USE_SSE)
|
286
|
+
#if defined(USE_AVX) || defined(USE_SSE) || defined(USE_AVX512)
|
254
287
|
if (dim % 16 == 0)
|
255
288
|
fstdistfunc_ = InnerProductSIMD16Ext;
|
256
289
|
else if (dim % 4 == 0)
|
data/ext/hnswlib/src/space_l2.h
CHANGED
@@ -19,7 +19,41 @@ namespace hnswlib {
|
|
19
19
|
return (res);
|
20
20
|
}
|
21
21
|
|
22
|
-
#if defined(
|
22
|
+
#if defined(USE_AVX512)
|
23
|
+
|
24
|
+
// Favor using AVX512 if available.
|
25
|
+
static float
|
26
|
+
L2SqrSIMD16Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
|
27
|
+
float *pVect1 = (float *) pVect1v;
|
28
|
+
float *pVect2 = (float *) pVect2v;
|
29
|
+
size_t qty = *((size_t *) qty_ptr);
|
30
|
+
float PORTABLE_ALIGN64 TmpRes[16];
|
31
|
+
size_t qty16 = qty >> 4;
|
32
|
+
|
33
|
+
const float *pEnd1 = pVect1 + (qty16 << 4);
|
34
|
+
|
35
|
+
__m512 diff, v1, v2;
|
36
|
+
__m512 sum = _mm512_set1_ps(0);
|
37
|
+
|
38
|
+
while (pVect1 < pEnd1) {
|
39
|
+
v1 = _mm512_loadu_ps(pVect1);
|
40
|
+
pVect1 += 16;
|
41
|
+
v2 = _mm512_loadu_ps(pVect2);
|
42
|
+
pVect2 += 16;
|
43
|
+
diff = _mm512_sub_ps(v1, v2);
|
44
|
+
// sum = _mm512_fmadd_ps(diff, diff, sum);
|
45
|
+
sum = _mm512_add_ps(sum, _mm512_mul_ps(diff, diff));
|
46
|
+
}
|
47
|
+
|
48
|
+
_mm512_store_ps(TmpRes, sum);
|
49
|
+
float res = TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3] + TmpRes[4] + TmpRes[5] + TmpRes[6] +
|
50
|
+
TmpRes[7] + TmpRes[8] + TmpRes[9] + TmpRes[10] + TmpRes[11] + TmpRes[12] +
|
51
|
+
TmpRes[13] + TmpRes[14] + TmpRes[15];
|
52
|
+
|
53
|
+
return (res);
|
54
|
+
}
|
55
|
+
|
56
|
+
#elif defined(USE_AVX)
|
23
57
|
|
24
58
|
// Favor using AVX if available.
|
25
59
|
static float
|
@@ -106,7 +140,7 @@ namespace hnswlib {
|
|
106
140
|
}
|
107
141
|
#endif
|
108
142
|
|
109
|
-
#if defined(USE_SSE) || defined(USE_AVX)
|
143
|
+
#if defined(USE_SSE) || defined(USE_AVX) || defined(USE_AVX512)
|
110
144
|
static float
|
111
145
|
L2SqrSIMD16ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
|
112
146
|
size_t qty = *((size_t *) qty_ptr);
|
@@ -175,7 +209,7 @@ namespace hnswlib {
|
|
175
209
|
L2Space() : data_size_(0), dim_(0) { }
|
176
210
|
L2Space(size_t dim) {
|
177
211
|
fstdistfunc_ = L2Sqr;
|
178
|
-
#if defined(USE_SSE) || defined(USE_AVX)
|
212
|
+
#if defined(USE_SSE) || defined(USE_AVX) || defined(USE_AVX512)
|
179
213
|
if (dim % 16 == 0)
|
180
214
|
fstdistfunc_ = L2SqrSIMD16Ext;
|
181
215
|
else if (dim % 4 == 0)
|
@@ -279,4 +313,4 @@ namespace hnswlib {
|
|
279
313
|
};
|
280
314
|
|
281
315
|
|
282
|
-
}
|
316
|
+
}
|
data/lib/hnswlib/version.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
# Hnswlib.rb provides Ruby bindings for the Hnswlib.
|
4
4
|
module Hnswlib
|
5
5
|
# The version of Hnswlib.rb you install.
|
6
|
-
VERSION = '0.
|
6
|
+
VERSION = '0.5.0'
|
7
7
|
|
8
8
|
# The version of Hnswlib included with gem.
|
9
|
-
HSWLIB_VERSION = '0.
|
9
|
+
HSWLIB_VERSION = '0.6.0'
|
10
10
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hnswlib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yoshoku
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Hnswlib.rb provides Ruby bindings for the Hnswlib.
|
14
14
|
email:
|
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
64
|
- !ruby/object:Gem::Version
|
65
65
|
version: '0'
|
66
66
|
requirements: []
|
67
|
-
rubygems_version: 3.2.
|
67
|
+
rubygems_version: 3.2.32
|
68
68
|
signing_key:
|
69
69
|
specification_version: 4
|
70
70
|
summary: Ruby bindings for the Hnswlib.
|