faiss 0.2.3 → 0.2.5
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 +9 -0
- data/LICENSE.txt +1 -1
- data/README.md +23 -21
- data/ext/faiss/extconf.rb +11 -0
- data/ext/faiss/index.cpp +4 -4
- data/ext/faiss/index_binary.cpp +6 -6
- data/ext/faiss/product_quantizer.cpp +4 -4
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +13 -0
- data/vendor/faiss/faiss/Clustering.cpp +32 -0
- data/vendor/faiss/faiss/Clustering.h +14 -0
- data/vendor/faiss/faiss/IVFlib.cpp +101 -2
- data/vendor/faiss/faiss/IVFlib.h +26 -2
- data/vendor/faiss/faiss/Index.cpp +36 -3
- data/vendor/faiss/faiss/Index.h +43 -6
- data/vendor/faiss/faiss/Index2Layer.cpp +24 -93
- data/vendor/faiss/faiss/Index2Layer.h +8 -17
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +610 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +253 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +299 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +199 -0
- data/vendor/faiss/faiss/IndexBinary.cpp +20 -4
- data/vendor/faiss/faiss/IndexBinary.h +18 -3
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +9 -2
- data/vendor/faiss/faiss/IndexBinaryFlat.h +4 -2
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -1
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +2 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +5 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +2 -1
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +17 -4
- data/vendor/faiss/faiss/IndexBinaryHash.h +8 -4
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +28 -13
- data/vendor/faiss/faiss/IndexBinaryIVF.h +10 -7
- data/vendor/faiss/faiss/IndexFastScan.cpp +626 -0
- data/vendor/faiss/faiss/IndexFastScan.h +145 -0
- data/vendor/faiss/faiss/IndexFlat.cpp +52 -69
- data/vendor/faiss/faiss/IndexFlat.h +16 -19
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +101 -0
- data/vendor/faiss/faiss/IndexFlatCodes.h +59 -0
- data/vendor/faiss/faiss/IndexHNSW.cpp +66 -138
- data/vendor/faiss/faiss/IndexHNSW.h +4 -2
- data/vendor/faiss/faiss/IndexIDMap.cpp +247 -0
- data/vendor/faiss/faiss/IndexIDMap.h +107 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +200 -40
- data/vendor/faiss/faiss/IndexIVF.h +59 -22
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +393 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +183 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +590 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +171 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +1290 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.h +213 -0
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +43 -26
- data/vendor/faiss/faiss/IndexIVFFlat.h +4 -2
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +238 -53
- data/vendor/faiss/faiss/IndexIVFPQ.h +6 -2
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +23 -852
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +7 -112
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFPQR.h +1 -1
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +63 -40
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +23 -7
- data/vendor/faiss/faiss/IndexLSH.cpp +8 -32
- data/vendor/faiss/faiss/IndexLSH.h +4 -16
- data/vendor/faiss/faiss/IndexLattice.cpp +7 -1
- data/vendor/faiss/faiss/IndexLattice.h +3 -1
- data/vendor/faiss/faiss/IndexNNDescent.cpp +4 -5
- data/vendor/faiss/faiss/IndexNNDescent.h +2 -1
- data/vendor/faiss/faiss/IndexNSG.cpp +37 -5
- data/vendor/faiss/faiss/IndexNSG.h +25 -1
- data/vendor/faiss/faiss/IndexPQ.cpp +108 -120
- data/vendor/faiss/faiss/IndexPQ.h +21 -22
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +15 -450
- data/vendor/faiss/faiss/IndexPQFastScan.h +15 -78
- data/vendor/faiss/faiss/IndexPreTransform.cpp +47 -8
- data/vendor/faiss/faiss/IndexPreTransform.h +15 -3
- data/vendor/faiss/faiss/IndexRefine.cpp +36 -4
- data/vendor/faiss/faiss/IndexRefine.h +14 -2
- data/vendor/faiss/faiss/IndexReplicas.cpp +4 -2
- data/vendor/faiss/faiss/IndexReplicas.h +2 -1
- data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +438 -0
- data/vendor/faiss/faiss/IndexRowwiseMinMax.h +92 -0
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +28 -43
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +8 -23
- data/vendor/faiss/faiss/IndexShards.cpp +4 -1
- data/vendor/faiss/faiss/IndexShards.h +2 -1
- data/vendor/faiss/faiss/MetaIndexes.cpp +5 -178
- data/vendor/faiss/faiss/MetaIndexes.h +3 -81
- data/vendor/faiss/faiss/VectorTransform.cpp +45 -1
- data/vendor/faiss/faiss/VectorTransform.h +25 -4
- data/vendor/faiss/faiss/clone_index.cpp +26 -3
- data/vendor/faiss/faiss/clone_index.h +3 -0
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +300 -0
- data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +24 -0
- data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +195 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +2058 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +408 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +2147 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +460 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +465 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +1618 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +251 -0
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +1452 -0
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +1 -0
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +2 -6
- data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
- data/vendor/faiss/faiss/gpu/GpuIndex.h +28 -4
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +2 -1
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +10 -8
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +75 -14
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +19 -32
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -31
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +22 -28
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +14 -0
- data/vendor/faiss/faiss/gpu/GpuResources.h +16 -3
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +3 -3
- data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +32 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +1 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +311 -75
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +10 -0
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +3 -0
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +2 -2
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +5 -4
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +331 -29
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +110 -19
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +0 -54
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -76
- data/vendor/faiss/faiss/impl/DistanceComputer.h +64 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +133 -32
- data/vendor/faiss/faiss/impl/HNSW.h +19 -16
- data/vendor/faiss/faiss/impl/IDSelector.cpp +125 -0
- data/vendor/faiss/faiss/impl/IDSelector.h +135 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +378 -217
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +106 -29
- data/vendor/faiss/faiss/impl/LookupTableScaler.h +77 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -0
- data/vendor/faiss/faiss/impl/NSG.cpp +1 -4
- data/vendor/faiss/faiss/impl/NSG.h +1 -1
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +383 -0
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +154 -0
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +225 -145
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +29 -10
- data/vendor/faiss/faiss/impl/Quantizer.h +43 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +521 -55
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +94 -16
- data/vendor/faiss/faiss/impl/ResultHandler.h +96 -0
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +108 -191
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +18 -18
- data/vendor/faiss/faiss/impl/index_read.cpp +338 -24
- data/vendor/faiss/faiss/impl/index_write.cpp +300 -18
- data/vendor/faiss/faiss/impl/io.cpp +1 -1
- data/vendor/faiss/faiss/impl/io_macros.h +20 -0
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +303 -0
- data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +56 -16
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +25 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +66 -25
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +75 -27
- data/vendor/faiss/faiss/index_factory.cpp +772 -412
- data/vendor/faiss/faiss/index_factory.h +3 -0
- data/vendor/faiss/faiss/index_io.h +5 -0
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -0
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +4 -1
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +2 -1
- data/vendor/faiss/faiss/python/python_callbacks.cpp +27 -0
- data/vendor/faiss/faiss/python/python_callbacks.h +15 -0
- data/vendor/faiss/faiss/utils/Heap.h +31 -15
- data/vendor/faiss/faiss/utils/distances.cpp +384 -58
- data/vendor/faiss/faiss/utils/distances.h +149 -18
- data/vendor/faiss/faiss/utils/distances_simd.cpp +776 -6
- data/vendor/faiss/faiss/utils/extra_distances.cpp +12 -7
- data/vendor/faiss/faiss/utils/extra_distances.h +3 -1
- data/vendor/faiss/faiss/utils/fp16-fp16c.h +21 -0
- data/vendor/faiss/faiss/utils/fp16-inl.h +101 -0
- data/vendor/faiss/faiss/utils/fp16.h +11 -0
- data/vendor/faiss/faiss/utils/hamming-inl.h +54 -0
- data/vendor/faiss/faiss/utils/hamming.cpp +0 -48
- data/vendor/faiss/faiss/utils/ordered_key_value.h +10 -0
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +62 -0
- data/vendor/faiss/faiss/utils/quantize_lut.h +20 -0
- data/vendor/faiss/faiss/utils/random.cpp +53 -0
- data/vendor/faiss/faiss/utils/random.h +5 -0
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +4 -0
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +6 -1
- data/vendor/faiss/faiss/utils/simdlib_neon.h +7 -2
- data/vendor/faiss/faiss/utils/utils.h +1 -1
- metadata +46 -5
- data/vendor/faiss/faiss/IndexResidual.cpp +0 -291
- data/vendor/faiss/faiss/IndexResidual.h +0 -152
|
@@ -19,6 +19,9 @@ Index* index_factory(
|
|
|
19
19
|
const char* description,
|
|
20
20
|
MetricType metric = METRIC_L2);
|
|
21
21
|
|
|
22
|
+
/// set to > 0 to get more logs from index_factory
|
|
23
|
+
FAISS_API extern int index_factory_verbose;
|
|
24
|
+
|
|
22
25
|
IndexBinary* index_binary_factory(int d, const char* description);
|
|
23
26
|
|
|
24
27
|
} // namespace faiss
|
|
@@ -50,6 +50,8 @@ const int IO_FLAG_READ_ONLY = 2;
|
|
|
50
50
|
const int IO_FLAG_ONDISK_SAME_DIR = 4;
|
|
51
51
|
// don't load IVF data to RAM, only list sizes
|
|
52
52
|
const int IO_FLAG_SKIP_IVF_DATA = 8;
|
|
53
|
+
// don't initialize precomputed table after loading
|
|
54
|
+
const int IO_FLAG_SKIP_PRECOMPUTE_TABLE = 16;
|
|
53
55
|
// try to memmap data (useful to load an ArrayInvertedLists as an
|
|
54
56
|
// OnDiskInvertedLists)
|
|
55
57
|
const int IO_FLAG_MMAP = IO_FLAG_SKIP_IVF_DATA | 0x646f0000;
|
|
@@ -63,7 +65,10 @@ IndexBinary* read_index_binary(FILE* f, int io_flags = 0);
|
|
|
63
65
|
IndexBinary* read_index_binary(IOReader* reader, int io_flags = 0);
|
|
64
66
|
|
|
65
67
|
void write_VectorTransform(const VectorTransform* vt, const char* fname);
|
|
68
|
+
void write_VectorTransform(const VectorTransform* vt, IOWriter* f);
|
|
69
|
+
|
|
66
70
|
VectorTransform* read_VectorTransform(const char* fname);
|
|
71
|
+
VectorTransform* read_VectorTransform(IOReader* f);
|
|
67
72
|
|
|
68
73
|
ProductQuantizer* read_ProductQuantizer(const char* fname);
|
|
69
74
|
ProductQuantizer* read_ProductQuantizer(IOReader* reader);
|
|
@@ -28,7 +28,10 @@ InvertedLists::~InvertedLists() {}
|
|
|
28
28
|
InvertedLists::idx_t InvertedLists::get_single_id(size_t list_no, size_t offset)
|
|
29
29
|
const {
|
|
30
30
|
assert(offset < list_size(list_no));
|
|
31
|
-
|
|
31
|
+
const idx_t* ids = get_ids(list_no);
|
|
32
|
+
idx_t id = ids[offset];
|
|
33
|
+
release_ids(list_no, ids);
|
|
34
|
+
return id;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
void InvertedLists::release_codes(size_t, const uint8_t*) const {}
|
|
@@ -278,13 +278,14 @@ void OnDiskInvertedLists::do_mmap() {
|
|
|
278
278
|
uint8_t* ptro =
|
|
279
279
|
(uint8_t*)mmap(nullptr, totsize, prot, MAP_SHARED, fileno(f), 0);
|
|
280
280
|
|
|
281
|
+
fclose(f);
|
|
282
|
+
|
|
281
283
|
FAISS_THROW_IF_NOT_FMT(
|
|
282
284
|
ptro != MAP_FAILED,
|
|
283
285
|
"could not mmap %s: %s",
|
|
284
286
|
filename.c_str(),
|
|
285
287
|
strerror(errno));
|
|
286
288
|
ptr = ptro;
|
|
287
|
-
fclose(f);
|
|
288
289
|
}
|
|
289
290
|
|
|
290
291
|
void OnDiskInvertedLists::update_totsize(size_t new_size) {
|
|
@@ -107,3 +107,30 @@ PyCallbackIOReader::~PyCallbackIOReader() {
|
|
|
107
107
|
PyThreadLock gil;
|
|
108
108
|
Py_DECREF(callback);
|
|
109
109
|
}
|
|
110
|
+
|
|
111
|
+
/***********************************************************
|
|
112
|
+
* Callbacks for IDSelector
|
|
113
|
+
***********************************************************/
|
|
114
|
+
|
|
115
|
+
PyCallbackIDSelector::PyCallbackIDSelector(PyObject* callback)
|
|
116
|
+
: callback(callback) {
|
|
117
|
+
PyThreadLock gil;
|
|
118
|
+
Py_INCREF(callback);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
bool PyCallbackIDSelector::is_member(idx_t id) const {
|
|
122
|
+
FAISS_THROW_IF_NOT((id >> 32) == 0);
|
|
123
|
+
PyThreadLock gil;
|
|
124
|
+
PyObject* result = PyObject_CallFunction(callback, "(n)", int(id));
|
|
125
|
+
if (result == NULL) {
|
|
126
|
+
FAISS_THROW_MSG("propagate py error");
|
|
127
|
+
}
|
|
128
|
+
bool b = PyObject_IsTrue(result);
|
|
129
|
+
Py_DECREF(result);
|
|
130
|
+
return b;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
PyCallbackIDSelector::~PyCallbackIDSelector() {
|
|
134
|
+
PyThreadLock gil;
|
|
135
|
+
Py_DECREF(callback);
|
|
136
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
+
#include <faiss/impl/IDSelector.h>
|
|
10
11
|
#include <faiss/impl/io.h>
|
|
11
12
|
#include <faiss/invlists/InvertedLists.h>
|
|
12
13
|
#include "Python.h"
|
|
@@ -43,3 +44,17 @@ struct PyCallbackIOReader : faiss::IOReader {
|
|
|
43
44
|
|
|
44
45
|
~PyCallbackIOReader() override;
|
|
45
46
|
};
|
|
47
|
+
|
|
48
|
+
/***********************************************************
|
|
49
|
+
* Callbacks for IDSelector
|
|
50
|
+
***********************************************************/
|
|
51
|
+
|
|
52
|
+
struct PyCallbackIDSelector : faiss::IDSelector {
|
|
53
|
+
PyObject* callback;
|
|
54
|
+
|
|
55
|
+
explicit PyCallbackIDSelector(PyObject* callback);
|
|
56
|
+
|
|
57
|
+
bool is_member(idx_t id) const override;
|
|
58
|
+
|
|
59
|
+
~PyCallbackIDSelector() override;
|
|
60
|
+
};
|
|
@@ -47,21 +47,25 @@ inline void heap_pop(size_t k, typename C::T* bh_val, typename C::TI* bh_ids) {
|
|
|
47
47
|
bh_val--; /* Use 1-based indexing for easier node->child translation */
|
|
48
48
|
bh_ids--;
|
|
49
49
|
typename C::T val = bh_val[k];
|
|
50
|
+
typename C::TI id = bh_ids[k];
|
|
50
51
|
size_t i = 1, i1, i2;
|
|
51
52
|
while (1) {
|
|
52
53
|
i1 = i << 1;
|
|
53
54
|
i2 = i1 + 1;
|
|
54
55
|
if (i1 > k)
|
|
55
56
|
break;
|
|
56
|
-
if (i2 == k + 1 ||
|
|
57
|
-
|
|
57
|
+
if ((i2 == k + 1) ||
|
|
58
|
+
C::cmp2(bh_val[i1], bh_val[i2], bh_ids[i1], bh_ids[i2])) {
|
|
59
|
+
if (C::cmp2(val, bh_val[i1], id, bh_ids[i1])) {
|
|
58
60
|
break;
|
|
61
|
+
}
|
|
59
62
|
bh_val[i] = bh_val[i1];
|
|
60
63
|
bh_ids[i] = bh_ids[i1];
|
|
61
64
|
i = i1;
|
|
62
65
|
} else {
|
|
63
|
-
if (C::
|
|
66
|
+
if (C::cmp2(val, bh_val[i2], id, bh_ids[i2])) {
|
|
64
67
|
break;
|
|
68
|
+
}
|
|
65
69
|
bh_val[i] = bh_val[i2];
|
|
66
70
|
bh_ids[i] = bh_ids[i2];
|
|
67
71
|
i = i2;
|
|
@@ -80,24 +84,28 @@ inline void heap_push(
|
|
|
80
84
|
typename C::T* bh_val,
|
|
81
85
|
typename C::TI* bh_ids,
|
|
82
86
|
typename C::T val,
|
|
83
|
-
typename C::TI
|
|
87
|
+
typename C::TI id) {
|
|
84
88
|
bh_val--; /* Use 1-based indexing for easier node->child translation */
|
|
85
89
|
bh_ids--;
|
|
86
90
|
size_t i = k, i_father;
|
|
87
91
|
while (i > 1) {
|
|
88
92
|
i_father = i >> 1;
|
|
89
|
-
if (!C::
|
|
93
|
+
if (!C::cmp2(val, bh_val[i_father], id, bh_ids[i_father])) {
|
|
94
|
+
/* the heap structure is ok */
|
|
90
95
|
break;
|
|
96
|
+
}
|
|
91
97
|
bh_val[i] = bh_val[i_father];
|
|
92
98
|
bh_ids[i] = bh_ids[i_father];
|
|
93
99
|
i = i_father;
|
|
94
100
|
}
|
|
95
101
|
bh_val[i] = val;
|
|
96
|
-
bh_ids[i] =
|
|
102
|
+
bh_ids[i] = id;
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
/**
|
|
100
|
-
*
|
|
105
|
+
/**
|
|
106
|
+
* Replaces the top element from the heap defined by bh_val[0..k-1] and
|
|
107
|
+
* bh_ids[0..k-1], and for identical bh_val[] values also sorts by bh_ids[]
|
|
108
|
+
* values.
|
|
101
109
|
*/
|
|
102
110
|
template <class C>
|
|
103
111
|
inline void heap_replace_top(
|
|
@@ -105,31 +113,39 @@ inline void heap_replace_top(
|
|
|
105
113
|
typename C::T* bh_val,
|
|
106
114
|
typename C::TI* bh_ids,
|
|
107
115
|
typename C::T val,
|
|
108
|
-
typename C::TI
|
|
116
|
+
typename C::TI id) {
|
|
109
117
|
bh_val--; /* Use 1-based indexing for easier node->child translation */
|
|
110
118
|
bh_ids--;
|
|
111
119
|
size_t i = 1, i1, i2;
|
|
112
120
|
while (1) {
|
|
113
121
|
i1 = i << 1;
|
|
114
122
|
i2 = i1 + 1;
|
|
115
|
-
if (i1 > k)
|
|
123
|
+
if (i1 > k) {
|
|
116
124
|
break;
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Note that C::cmp2() is a bool function answering
|
|
128
|
+
// `(a1 > b1) || ((a1 == b1) && (a2 > b2))` for max
|
|
129
|
+
// heap and same with the `<` sign for min heap.
|
|
130
|
+
if ((i2 == k + 1) ||
|
|
131
|
+
C::cmp2(bh_val[i1], bh_val[i2], bh_ids[i1], bh_ids[i2])) {
|
|
132
|
+
if (C::cmp2(val, bh_val[i1], id, bh_ids[i1])) {
|
|
119
133
|
break;
|
|
134
|
+
}
|
|
120
135
|
bh_val[i] = bh_val[i1];
|
|
121
136
|
bh_ids[i] = bh_ids[i1];
|
|
122
137
|
i = i1;
|
|
123
138
|
} else {
|
|
124
|
-
if (C::
|
|
139
|
+
if (C::cmp2(val, bh_val[i2], id, bh_ids[i2])) {
|
|
125
140
|
break;
|
|
141
|
+
}
|
|
126
142
|
bh_val[i] = bh_val[i2];
|
|
127
143
|
bh_ids[i] = bh_ids[i2];
|
|
128
144
|
i = i2;
|
|
129
145
|
}
|
|
130
146
|
}
|
|
131
147
|
bh_val[i] = val;
|
|
132
|
-
bh_ids[i] =
|
|
148
|
+
bh_ids[i] = id;
|
|
133
149
|
}
|
|
134
150
|
|
|
135
151
|
/* Partial instanciation for heaps with TI = int64_t */
|
|
@@ -294,7 +310,7 @@ inline void maxheap_addn(
|
|
|
294
310
|
* Heap finalization (reorder elements)
|
|
295
311
|
*******************************************************************/
|
|
296
312
|
|
|
297
|
-
/* This function maps a binary heap into
|
|
313
|
+
/* This function maps a binary heap into a sorted structure.
|
|
298
314
|
It returns the number */
|
|
299
315
|
template <typename C>
|
|
300
316
|
inline size_t heap_reorder(
|