/var/local/thirdparty/installed/include/roaring/array_util.h
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | #ifndef ARRAY_UTIL_H | 
| 2 |  | #define ARRAY_UTIL_H | 
| 3 |  |  | 
| 4 |  | #include <stddef.h>  // for size_t | 
| 5 |  | #include <stdint.h> | 
| 6 |  |  | 
| 7 |  | #include <roaring/portability.h> | 
| 8 |  |  | 
| 9 |  | #if CROARING_IS_X64 | 
| 10 |  | #ifndef CROARING_COMPILER_SUPPORTS_AVX512 | 
| 11 |  | #error "CROARING_COMPILER_SUPPORTS_AVX512 needs to be defined." | 
| 12 |  | #endif // CROARING_COMPILER_SUPPORTS_AVX512 | 
| 13 |  | #endif | 
| 14 |  |  | 
| 15 |  | #ifdef __cplusplus | 
| 16 |  | extern "C" { namespace roaring { namespace internal { | 
| 17 |  | #endif | 
| 18 |  |  | 
| 19 |  | /* | 
| 20 |  |  *  Good old binary search. | 
| 21 |  |  *  Assumes that array is sorted, has logarithmic complexity. | 
| 22 |  |  *  if the result is x, then: | 
| 23 |  |  *     if ( x>0 )  you have array[x] = ikey | 
| 24 |  |  *     if ( x<0 ) then inserting ikey at position -x-1 in array (insuring that array[-x-1]=ikey) | 
| 25 |  |  *                   keys the array sorted. | 
| 26 |  |  */ | 
| 27 |  | inline int32_t binarySearch(const uint16_t *array, int32_t lenarray, | 
| 28 | 0 |                             uint16_t ikey) { | 
| 29 | 0 |     int32_t low = 0; | 
| 30 | 0 |     int32_t high = lenarray - 1; | 
| 31 | 0 |     while (low <= high) { | 
| 32 | 0 |         int32_t middleIndex = (low + high) >> 1; | 
| 33 | 0 |         uint16_t middleValue = array[middleIndex]; | 
| 34 | 0 |         if (middleValue < ikey) { | 
| 35 | 0 |             low = middleIndex + 1; | 
| 36 | 0 |         } else if (middleValue > ikey) { | 
| 37 | 0 |             high = middleIndex - 1; | 
| 38 | 0 |         } else { | 
| 39 | 0 |             return middleIndex; | 
| 40 | 0 |         } | 
| 41 | 0 |     } | 
| 42 | 0 |     return -(low + 1); | 
| 43 | 0 | } | 
| 44 |  |  | 
| 45 |  | /** | 
| 46 |  |  * Galloping search | 
| 47 |  |  * Assumes that array is sorted, has logarithmic complexity. | 
| 48 |  |  * if the result is x, then if x = length, you have that all values in array between pos and length | 
| 49 |  |  *    are smaller than min. | 
| 50 |  |  * otherwise returns the first index x such that array[x] >= min. | 
| 51 |  |  */ | 
| 52 |  | static inline int32_t advanceUntil(const uint16_t *array, int32_t pos, | 
| 53 | 0 |                                    int32_t length, uint16_t min) { | 
| 54 | 0 |     int32_t lower = pos + 1; | 
| 55 | 0 | 
 | 
| 56 | 0 |     if ((lower >= length) || (array[lower] >= min)) { | 
| 57 | 0 |         return lower; | 
| 58 | 0 |     } | 
| 59 | 0 | 
 | 
| 60 | 0 |     int32_t spansize = 1; | 
| 61 | 0 | 
 | 
| 62 | 0 |     while ((lower + spansize < length) && (array[lower + spansize] < min)) { | 
| 63 | 0 |         spansize <<= 1; | 
| 64 | 0 |     } | 
| 65 | 0 |     int32_t upper = (lower + spansize < length) ? lower + spansize : length - 1; | 
| 66 | 0 | 
 | 
| 67 | 0 |     if (array[upper] == min) { | 
| 68 | 0 |         return upper; | 
| 69 | 0 |     } | 
| 70 | 0 |     if (array[upper] < min) { | 
| 71 | 0 |         // means | 
| 72 | 0 |         // array | 
| 73 | 0 |         // has no | 
| 74 | 0 |         // item | 
| 75 | 0 |         // >= min | 
| 76 | 0 |         // pos = array.length; | 
| 77 | 0 |         return length; | 
| 78 | 0 |     } | 
| 79 | 0 | 
 | 
| 80 | 0 |     // we know that the next-smallest span was too small | 
| 81 | 0 |     lower += (spansize >> 1); | 
| 82 | 0 | 
 | 
| 83 | 0 |     int32_t mid = 0; | 
| 84 | 0 |     while (lower + 1 != upper) { | 
| 85 | 0 |         mid = (lower + upper) >> 1; | 
| 86 | 0 |         if (array[mid] == min) { | 
| 87 | 0 |             return mid; | 
| 88 | 0 |         } else if (array[mid] < min) { | 
| 89 | 0 |             lower = mid; | 
| 90 | 0 |         } else { | 
| 91 | 0 |             upper = mid; | 
| 92 | 0 |         } | 
| 93 | 0 |     } | 
| 94 | 0 |     return upper; | 
| 95 | 0 | } Unexecuted instantiation: bkd_writer.cpp:_ZN7roaring8internalL12advanceUntilEPKtiitUnexecuted instantiation: bkd_reader.cpp:_ZN7roaring8internalL12advanceUntilEPKtiitUnexecuted instantiation: packed_index_tree.cpp:_ZN7roaring8internalL12advanceUntilEPKtiitUnexecuted instantiation: index_tree.cpp:_ZN7roaring8internalL12advanceUntilEPKtiitUnexecuted instantiation: legacy_index_tree.cpp:_ZN7roaring8internalL12advanceUntilEPKtiitUnexecuted instantiation: docids_writer.cpp:_ZN7roaring8internalL12advanceUntilEPKtiitUnexecuted instantiation: IndexWriter.cpp:_ZN7roaring8internalL12advanceUntilEPKtiit | 
| 96 |  |  | 
| 97 |  | /** | 
| 98 |  |  * Returns number of elements which are less than ikey. | 
| 99 |  |  * Array elements must be unique and sorted. | 
| 100 |  |  */ | 
| 101 |  | static inline int32_t count_less(const uint16_t *array, int32_t lenarray, | 
| 102 | 0 |                                  uint16_t ikey) { | 
| 103 | 0 |     if (lenarray == 0) return 0; | 
| 104 | 0 |     int32_t pos = binarySearch(array, lenarray, ikey); | 
| 105 | 0 |     return pos >= 0 ? pos : -(pos+1); | 
| 106 | 0 | } Unexecuted instantiation: bkd_writer.cpp:_ZN7roaring8internalL10count_lessEPKtitUnexecuted instantiation: bkd_reader.cpp:_ZN7roaring8internalL10count_lessEPKtitUnexecuted instantiation: packed_index_tree.cpp:_ZN7roaring8internalL10count_lessEPKtitUnexecuted instantiation: index_tree.cpp:_ZN7roaring8internalL10count_lessEPKtitUnexecuted instantiation: legacy_index_tree.cpp:_ZN7roaring8internalL10count_lessEPKtitUnexecuted instantiation: docids_writer.cpp:_ZN7roaring8internalL10count_lessEPKtitUnexecuted instantiation: IndexWriter.cpp:_ZN7roaring8internalL10count_lessEPKtit | 
| 107 |  |  | 
| 108 |  | /** | 
| 109 |  |  * Returns number of elements which are greater than ikey. | 
| 110 |  |  * Array elements must be unique and sorted. | 
| 111 |  |  */ | 
| 112 |  | static inline int32_t count_greater(const uint16_t *array, int32_t lenarray, | 
| 113 | 0 |                                     uint16_t ikey) { | 
| 114 | 0 |     if (lenarray == 0) return 0; | 
| 115 | 0 |     int32_t pos = binarySearch(array, lenarray, ikey); | 
| 116 | 0 |     if (pos >= 0) { | 
| 117 | 0 |         return lenarray - (pos+1); | 
| 118 | 0 |     } else { | 
| 119 | 0 |         return lenarray - (-pos-1); | 
| 120 | 0 |     } | 
| 121 | 0 | } Unexecuted instantiation: bkd_writer.cpp:_ZN7roaring8internalL13count_greaterEPKtitUnexecuted instantiation: bkd_reader.cpp:_ZN7roaring8internalL13count_greaterEPKtitUnexecuted instantiation: packed_index_tree.cpp:_ZN7roaring8internalL13count_greaterEPKtitUnexecuted instantiation: index_tree.cpp:_ZN7roaring8internalL13count_greaterEPKtitUnexecuted instantiation: legacy_index_tree.cpp:_ZN7roaring8internalL13count_greaterEPKtitUnexecuted instantiation: docids_writer.cpp:_ZN7roaring8internalL13count_greaterEPKtitUnexecuted instantiation: IndexWriter.cpp:_ZN7roaring8internalL13count_greaterEPKtit | 
| 122 |  |  | 
| 123 |  | /** | 
| 124 |  |  * From Schlegel et al., Fast Sorted-Set Intersection using SIMD Instructions | 
| 125 |  |  * Optimized by D. Lemire on May 3rd 2013 | 
| 126 |  |  * | 
| 127 |  |  * C should have capacity greater than the minimum of s_1 and s_b + 8 | 
| 128 |  |  * where 8 is sizeof(__m128i)/sizeof(uint16_t). | 
| 129 |  |  */ | 
| 130 |  | int32_t intersect_vector16(const uint16_t *__restrict__ A, size_t s_a, | 
| 131 |  |                            const uint16_t *__restrict__ B, size_t s_b, | 
| 132 |  |                            uint16_t *C); | 
| 133 |  |  | 
| 134 |  | int32_t intersect_vector16_inplace(uint16_t *__restrict__ A, size_t s_a, | 
| 135 |  |                            const uint16_t *__restrict__ B, size_t s_b); | 
| 136 |  |  | 
| 137 |  | /** | 
| 138 |  |  * Take an array container and write it out to a 32-bit array, using base | 
| 139 |  |  * as the offset. | 
| 140 |  |  */ | 
| 141 |  | int array_container_to_uint32_array_vector16(void *vout, const uint16_t* array, size_t cardinality, | 
| 142 |  |                                     uint32_t base); | 
| 143 |  | #if CROARING_COMPILER_SUPPORTS_AVX512 | 
| 144 |  | int avx512_array_container_to_uint32_array(void *vout, const uint16_t* array, size_t cardinality, | 
| 145 |  |                                     uint32_t base); | 
| 146 |  | #endif | 
| 147 |  | /** | 
| 148 |  |  * Compute the cardinality of the intersection using SSE4 instructions | 
| 149 |  |  */ | 
| 150 |  | int32_t intersect_vector16_cardinality(const uint16_t *__restrict__ A, | 
| 151 |  |                                        size_t s_a, | 
| 152 |  |                                        const uint16_t *__restrict__ B, | 
| 153 |  |                                        size_t s_b); | 
| 154 |  |  | 
| 155 |  | /* Computes the intersection between one small and one large set of uint16_t. | 
| 156 |  |  * Stores the result into buffer and return the number of elements. */ | 
| 157 |  | int32_t intersect_skewed_uint16(const uint16_t *smallarray, size_t size_s, | 
| 158 |  |                                 const uint16_t *largearray, size_t size_l, | 
| 159 |  |                                 uint16_t *buffer); | 
| 160 |  |  | 
| 161 |  | /* Computes the size of the intersection between one small and one large set of | 
| 162 |  |  * uint16_t. */ | 
| 163 |  | int32_t intersect_skewed_uint16_cardinality(const uint16_t *smallarray, | 
| 164 |  |                                             size_t size_s, | 
| 165 |  |                                             const uint16_t *largearray, | 
| 166 |  |                                             size_t size_l); | 
| 167 |  |  | 
| 168 |  |  | 
| 169 |  | /* Check whether the size of the intersection between one small and one large set of uint16_t is non-zero. */ | 
| 170 |  | bool intersect_skewed_uint16_nonempty(const uint16_t *smallarray, size_t size_s, | 
| 171 |  |                                 const uint16_t *largearray, size_t size_l); | 
| 172 |  | /** | 
| 173 |  |  * Generic intersection function. | 
| 174 |  |  */ | 
| 175 |  | int32_t intersect_uint16(const uint16_t *A, const size_t lenA, | 
| 176 |  |                          const uint16_t *B, const size_t lenB, uint16_t *out); | 
| 177 |  | /** | 
| 178 |  |  * Compute the size of the intersection (generic). | 
| 179 |  |  */ | 
| 180 |  | int32_t intersect_uint16_cardinality(const uint16_t *A, const size_t lenA, | 
| 181 |  |                                      const uint16_t *B, const size_t lenB); | 
| 182 |  |  | 
| 183 |  | /** | 
| 184 |  |  * Checking whether the size of the intersection  is non-zero. | 
| 185 |  |  */ | 
| 186 |  | bool intersect_uint16_nonempty(const uint16_t *A, const size_t lenA, | 
| 187 |  |                          const uint16_t *B, const size_t lenB); | 
| 188 |  | /** | 
| 189 |  |  * Generic union function. | 
| 190 |  |  */ | 
| 191 |  | size_t union_uint16(const uint16_t *set_1, size_t size_1, const uint16_t *set_2, | 
| 192 |  |                     size_t size_2, uint16_t *buffer); | 
| 193 |  |  | 
| 194 |  | /** | 
| 195 |  |  * Generic XOR function. | 
| 196 |  |  */ | 
| 197 |  | int32_t xor_uint16(const uint16_t *array_1, int32_t card_1, | 
| 198 |  |                    const uint16_t *array_2, int32_t card_2, uint16_t *out); | 
| 199 |  |  | 
| 200 |  | /** | 
| 201 |  |  * Generic difference function (ANDNOT). | 
| 202 |  |  */ | 
| 203 |  | int difference_uint16(const uint16_t *a1, int length1, const uint16_t *a2, | 
| 204 |  |                       int length2, uint16_t *a_out); | 
| 205 |  |  | 
| 206 |  | /** | 
| 207 |  |  * Generic intersection function. | 
| 208 |  |  */ | 
| 209 |  | size_t intersection_uint32(const uint32_t *A, const size_t lenA, | 
| 210 |  |                            const uint32_t *B, const size_t lenB, uint32_t *out); | 
| 211 |  |  | 
| 212 |  | /** | 
| 213 |  |  * Generic intersection function, returns just the cardinality. | 
| 214 |  |  */ | 
| 215 |  | size_t intersection_uint32_card(const uint32_t *A, const size_t lenA, | 
| 216 |  |                                 const uint32_t *B, const size_t lenB); | 
| 217 |  |  | 
| 218 |  | /** | 
| 219 |  |  * Generic union function. | 
| 220 |  |  */ | 
| 221 |  | size_t union_uint32(const uint32_t *set_1, size_t size_1, const uint32_t *set_2, | 
| 222 |  |                     size_t size_2, uint32_t *buffer); | 
| 223 |  |  | 
| 224 |  | /** | 
| 225 |  |  * A fast SSE-based union function. | 
| 226 |  |  */ | 
| 227 |  | uint32_t union_vector16(const uint16_t *__restrict__ set_1, uint32_t size_1, | 
| 228 |  |                         const uint16_t *__restrict__ set_2, uint32_t size_2, | 
| 229 |  |                         uint16_t *__restrict__ buffer); | 
| 230 |  | /** | 
| 231 |  |  * A fast SSE-based XOR function. | 
| 232 |  |  */ | 
| 233 |  | uint32_t xor_vector16(const uint16_t *__restrict__ array1, uint32_t length1, | 
| 234 |  |                       const uint16_t *__restrict__ array2, uint32_t length2, | 
| 235 |  |                       uint16_t *__restrict__ output); | 
| 236 |  |  | 
| 237 |  | /** | 
| 238 |  |  * A fast SSE-based difference function. | 
| 239 |  |  */ | 
| 240 |  | int32_t difference_vector16(const uint16_t *__restrict__ A, size_t s_a, | 
| 241 |  |                             const uint16_t *__restrict__ B, size_t s_b, | 
| 242 |  |                             uint16_t *C); | 
| 243 |  |  | 
| 244 |  | /** | 
| 245 |  |  * Generic union function, returns just the cardinality. | 
| 246 |  |  */ | 
| 247 |  | size_t union_uint32_card(const uint32_t *set_1, size_t size_1, | 
| 248 |  |                          const uint32_t *set_2, size_t size_2); | 
| 249 |  |  | 
| 250 |  | /** | 
| 251 |  | * combines union_uint16 and  union_vector16 optimally | 
| 252 |  | */ | 
| 253 |  | size_t fast_union_uint16(const uint16_t *set_1, size_t size_1, const uint16_t *set_2, | 
| 254 |  |                     size_t size_2, uint16_t *buffer); | 
| 255 |  |  | 
| 256 |  |  | 
| 257 |  | bool memequals(const void *s1, const void *s2, size_t n); | 
| 258 |  |  | 
| 259 |  | #ifdef __cplusplus | 
| 260 |  | } } }  // extern "C" { namespace roaring { namespace internal { | 
| 261 |  | #endif | 
| 262 |  |  | 
| 263 |  | #endif |