VariantKey  5.4.1
Numerical Encoding for Human Genetic Variants
binsearch.h
Go to the documentation of this file.
1 // Copyright (c) 2017-2018 Nicola Asuni - Tecnick.com
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
51 #ifndef VARIANTKEY_BINSEARCH_H
52 #define VARIANTKEY_BINSEARCH_H
53 
54 #include <inttypes.h>
55 #include <fcntl.h>
56 #include <stdbool.h>
57 #include <unistd.h>
58 #include <sys/mman.h>
59 #include <sys/stat.h>
60 
61 // Account for Endianness
62 
64 
65 #ifdef WORDS_BIGENDIAN
66 #undef BINSEARCH_BIG_ENDIAN
67 #define BINSEARCH_BIG_ENDIAN 1
68 #endif
69 
70 #if defined(BINSEARCH_LITTLE_ENDIAN) && defined(BINSEARCH_BIG_ENDIAN)
71 #error
72 #endif
73 
74 #if !defined(BINSEARCH_LITTLE_ENDIAN) && !defined(BINSEARCH_BIG_ENDIAN)
75 #define BINSEARCH_UNKNOWN_ENDIAN 1
76 #endif
77 
78 #if !defined(bswap_16) || !defined(bswap_32) || !defined(bswap_64)
79 #undef bswap_16
80 #undef bswap_32
81 #undef bswap_64
82 
83 #if defined(HAVE_BUILTIN_BSWAP) || defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5))
84 #define bswap_16(x) __builtin_bswap16(x)
85 #define bswap_32(x) __builtin_bswap32(x)
86 #define bswap_64(x) __builtin_bswap64(x)
87 #endif
88 
89 #endif
90 
91 #if defined(BINSEARCH_UNKNOWN_ENDIAN) || !defined(bswap_64)
92 
93 #ifdef _MSC_VER
94 
95 #undef bswap_16
96 #undef bswap_32
97 #undef bswap_64
98 #define bswap_16(x) _byteswap_ushort(x)
99 #define bswap_32(x) _byteswap_ulong(x)
100 #define bswap_64(x) _byteswap_uint64(x)
101 
102 #elif defined(__APPLE__)
103 
104 // Mac OS X / Darwin
105 #include <libkern/OSByteOrder.h>
106 #undef bswap_16
107 #undef bswap_32
108 #undef bswap_64
109 #define bswap_16(x) OSSwapInt16(x)
110 #define bswap_32(x) OSSwapInt32(x)
111 #define bswap_64(x) OSSwapInt64(x)
112 
113 #elif defined(__sun) || defined(sun)
114 
115 #include <sys/byteorder.h>
116 #undef bswap_16
117 #undef bswap_32
118 #undef bswap_64
119 #define bswap_16(x) BSWAP_16(x)
120 #define bswap_32(x) BSWAP_32(x)
121 #define bswap_64(x) BSWAP_64(x)
122 
123 #elif defined(__FreeBSD__)
124 
125 #include <sys/endian.h>
126 #undef bswap_16
127 #undef bswap_32
128 #undef bswap_64
129 #define bswap_16(x) bswap16(x)
130 #define bswap_32(x) bswap32(x)
131 #define bswap_64(x) bswap64(x)
132 
133 #elif defined(__OpenBSD__)
134 
135 #include <sys/types.h>
136 #undef bswap_16
137 #undef bswap_32
138 #undef bswap_64
139 #define bswap_16(x) swap16(x)
140 #define bswap_32(x) swap32(x)
141 #define bswap_64(x) swap64(x)
142 
143 #elif defined(__NetBSD__)
144 
145 #include <sys/types.h>
146 #include <machine/bswap.h>
147 #if defined(__BSWAP_RENAME) && !defined(__bswap_32)
148 #undef bswap_16
149 #undef bswap_32
150 #undef bswap_64
151 #define bswap_16(x) bswap16(x)
152 #define bswap_32(x) bswap32(x)
153 #define bswap_64(x) bswap64(x)
154 #endif
155 
156 #else
157 
158 #undef bswap_16
159 #undef bswap_32
160 #undef bswap_64
161 #include <byteswap.h>
162 
163 #endif
164 
165 #ifdef WORDS_BIGENDIAN
166 #define BINSEARCH_BIG_ENDIAN 1
167 #endif
168 
169 #endif
170 
172 
173 #define order_be_uint8_t(x) (x)
174 #define order_le_uint8_t(x) (x)
175 
176 #ifdef BINSEARCH_BIG_ENDIAN
177 #define order_be_uint16_t(x) (x)
178 #define order_be_uint32_t(x) (x)
179 #define order_be_uint64_t(x) (x)
180 #define order_le_uint16_t(x) (bswap_16(x))
181 #define order_le_uint32_t(x) (bswap_32(x))
182 #define order_le_uint64_t(x) (bswap_64(x))
183 #else
184 #define order_be_uint16_t(x) (bswap_16(x))
185 #define order_be_uint32_t(x) (bswap_32(x))
186 #define order_be_uint64_t(x) (bswap_64(x))
187 #define order_le_uint16_t(x) (x)
188 #define order_le_uint32_t(x) (x)
189 #define order_le_uint64_t(x) (x)
190 #endif
191 
192 #define MAXCOLS 256
193 
194 
203 #define get_address(blklen, blkpos, item) (((blklen) * (item)) + (blkpos))
204 
213 #define get_middle_point(first, last) ((first) + (((last) - (first)) >> 1))
214 
224 #define get_src_offset(T, src, offset) ((const T *)((src) + (offset)))
225 
229 typedef struct mmfile_t
230 {
231  uint8_t *src;
232  int fd;
233  uint64_t size;
234  uint64_t doffset;
235  uint64_t dlength;
236  uint64_t nrows;
237  uint8_t ncols;
238  uint8_t ctbytes[MAXCOLS];
239  uint64_t index[MAXCOLS];
240 } mmfile_t;
241 
248 #define define_bytes_to(O, T) \
249  \
254 static inline T bytes_##O##_to_##T(const uint8_t *src, uint64_t i) \
255 { \
256  return order_##O##_##T(*((const T *)(src + i))); \
257 }
258 
259 define_bytes_to(be, uint8_t)
260 define_bytes_to(be, uint16_t)
261 define_bytes_to(be, uint32_t)
262 define_bytes_to(be, uint64_t)
263 define_bytes_to(le, uint8_t)
264 define_bytes_to(le, uint16_t)
265 define_bytes_to(le, uint32_t)
266 define_bytes_to(le, uint64_t)
267 
273 #define define_get_src_offset(T) \
274  \
279 static inline const T *get_src_offset_##T(const uint8_t *src, uint64_t offset) \
280 { \
281  return get_src_offset(T, src, offset); \
282 }
283 
288 
289 #define GET_MIDDLE_BLOCK(O, T) order_##O##_##T(*(get_src_offset(T, src, get_address(blklen, blkpos, middle))))
290 
291 #define FIND_START_LOOP_BLOCK(T) \
292  uint64_t middle, notfound = *last; \
293  T x; \
294  while (*first < *last) \
295  { \
296  middle = get_middle_point(*first, *last); \
297 
298 #define FIND_END_LOOP_BLOCK \
299  if (x == search) \
300  { \
301  return middle; \
302  } \
303  if (*first > 0) \
304  { \
305  --(*first); \
306  } \
307  return notfound;
308 
309 #define SUB_ITEM_VARS(T) \
310  T bitmask = ((T)1 << (bitend - bitstart)); \
311  bitmask ^= (bitmask - 1); \
312  const uint8_t rshift = (((uint8_t)(sizeof(T) * 8) - 1) - bitend);
313 
314 #define GET_ITEM_TASK(O, T) \
315  x = GET_MIDDLE_BLOCK(O, T);
316 
317 #define COL_GET_ITEM_TASK \
318  x = *(src + middle);
319 
320 #define GET_SUB_ITEM_TASK(O, T) \
321  x = ((GET_MIDDLE_BLOCK(O, T) >> rshift) & bitmask);
322 
323 #define COL_GET_SUB_ITEM_TASK \
324  x = ((*(src + middle) >> rshift) & bitmask);
325 
326 #define FIND_FIRST_INNER_CHECK \
327  if (x < search) { \
328  *first = middle; \
329  ++(*first); \
330  } \
331  else \
332  { \
333  *last = middle; \
334  } \
335  } \
336  middle = *first;
337 
338 #define FIND_LAST_INNER_CHECK \
339  if (x > search) { \
340  *last = middle; \
341  } \
342  else \
343  { \
344  *first = middle; \
345  ++(*first); \
346  } \
347  } \
348  middle = *first; \
349  --middle;
350 
351 #define HAS_NEXT_START_BLOCK \
352  if (*pos >= (last - 1)) \
353  { \
354  return 0; \
355  } \
356  ++(*pos);
357 
358 #define HAS_PREV_START_BLOCK \
359  if (*pos <= first) { \
360  return 0; \
361  } \
362  --(*pos);
363 
364 #define GET_POS_BLOCK(O, T) order_##O##_##T(*(get_src_offset(T, src, get_address(blklen, blkpos, *pos))))
365 
366 #define HAS_END_BLOCK(O, T) \
367  return (GET_POS_BLOCK(O, T) == search);
368 
369 #define COL_HAS_END_BLOCK(T) \
370  return (*(src + *pos) == search);
371 
372 #define HAS_SUB_END_BLOCK(O, T) \
373  return (((GET_POS_BLOCK(O, T) >> rshift) & bitmask) == search);
374 
375 #define COL_HAS_SUB_END_BLOCK(T) \
376  return (((*(src + *pos) >> rshift) & bitmask) == search);
377 
385 #define define_find_first(O, T) \
386  \
397 static inline uint64_t find_first_##O##_##T(const uint8_t *src, uint64_t blklen, uint64_t blkpos, uint64_t *first, uint64_t *last, T search) \
398 { \
399 FIND_START_LOOP_BLOCK(T) \
400 GET_ITEM_TASK(O, T) \
401 FIND_FIRST_INNER_CHECK \
402 GET_ITEM_TASK(O, T) \
403 FIND_END_LOOP_BLOCK \
404 }
405 
406 define_find_first(be, uint8_t)
407 define_find_first(be, uint16_t)
408 define_find_first(be, uint32_t)
409 define_find_first(be, uint64_t)
410 define_find_first(le, uint8_t)
411 define_find_first(le, uint16_t)
412 define_find_first(le, uint32_t)
413 define_find_first(le, uint64_t)
414 
422 #define define_find_first_sub(O, T) \
423  \
436 static inline uint64_t find_first_sub_##O##_##T(const uint8_t *src, uint64_t blklen, uint64_t blkpos, uint8_t bitstart, uint8_t bitend, uint64_t *first, uint64_t *last, T search) \
437 { \
438 SUB_ITEM_VARS(T) \
439 FIND_START_LOOP_BLOCK(T) \
440 GET_SUB_ITEM_TASK(O, T) \
441 FIND_FIRST_INNER_CHECK \
442 GET_SUB_ITEM_TASK(O, T) \
443 FIND_END_LOOP_BLOCK \
444 }
445 
454 
462 #define define_find_last(O, T) \
463  \
474 static inline uint64_t find_last_##O##_##T(const uint8_t *src, uint64_t blklen, uint64_t blkpos, uint64_t *first, uint64_t *last, T search) \
475 { \
476 FIND_START_LOOP_BLOCK(T) \
477 GET_ITEM_TASK(O, T) \
478 FIND_LAST_INNER_CHECK \
479 GET_ITEM_TASK(O, T) \
480 FIND_END_LOOP_BLOCK \
481 }
482 
483 define_find_last(be, uint8_t)
484 define_find_last(be, uint16_t)
485 define_find_last(be, uint32_t)
486 define_find_last(be, uint64_t)
487 define_find_last(le, uint8_t)
488 define_find_last(le, uint16_t)
489 define_find_last(le, uint32_t)
490 define_find_last(le, uint64_t)
491 
499 #define define_find_last_sub(O, T) \
500  \
513 static inline uint64_t find_last_sub_##O##_##T(const uint8_t *src, uint64_t blklen, uint64_t blkpos, uint8_t bitstart, uint8_t bitend, uint64_t *first, uint64_t *last, T search) \
514 { \
515 SUB_ITEM_VARS(T) \
516 FIND_START_LOOP_BLOCK(T) \
517 GET_SUB_ITEM_TASK(O, T) \
518 FIND_LAST_INNER_CHECK \
519 GET_SUB_ITEM_TASK(O, T) \
520 FIND_END_LOOP_BLOCK \
521 }
522 
524 define_find_last_sub(be, uint16_t)
525 define_find_last_sub(be, uint32_t)
526 define_find_last_sub(be, uint64_t)
528 define_find_last_sub(le, uint16_t)
529 define_find_last_sub(le, uint32_t)
530 define_find_last_sub(le, uint64_t)
531 
538 #define define_has_next(O, T) \
539  \
552 static inline bool has_next_##O##_##T(const uint8_t *src, uint64_t blklen, uint64_t blkpos, uint64_t *pos, uint64_t last, T search) \
553 { \
554 HAS_NEXT_START_BLOCK \
555 HAS_END_BLOCK(O, T) \
556 }
557 
558 define_has_next(be, uint8_t)
559 define_has_next(be, uint16_t)
560 define_has_next(be, uint32_t)
561 define_has_next(be, uint64_t)
562 define_has_next(le, uint8_t)
563 define_has_next(le, uint16_t)
564 define_has_next(le, uint32_t)
565 define_has_next(le, uint64_t)
566 
573 #define define_has_next_sub(O, T) \
574  \
589 static inline bool has_next_sub_##O##_##T(const uint8_t *src, uint64_t blklen, uint64_t blkpos, uint8_t bitstart, uint8_t bitend, uint64_t *pos, uint64_t last, T search) \
590 { \
591 HAS_NEXT_START_BLOCK \
592 SUB_ITEM_VARS(T) \
593 HAS_SUB_END_BLOCK(O, T) \
594 }
595 
597 define_has_next_sub(be, uint16_t)
598 define_has_next_sub(be, uint32_t)
599 define_has_next_sub(be, uint64_t)
601 define_has_next_sub(le, uint16_t)
602 define_has_next_sub(le, uint32_t)
603 define_has_next_sub(le, uint64_t)
604 
611 #define define_has_prev(O, T) \
612  \
625 static inline bool has_prev_##O##_##T(const uint8_t *src, uint64_t blklen, uint64_t blkpos, uint64_t first, uint64_t *pos, T search) \
626 { \
627 HAS_PREV_START_BLOCK \
628 HAS_END_BLOCK(O, T) \
629 }
630 
631 define_has_prev(be, uint8_t)
632 define_has_prev(be, uint16_t)
633 define_has_prev(be, uint32_t)
634 define_has_prev(be, uint64_t)
635 define_has_prev(le, uint8_t)
636 define_has_prev(le, uint16_t)
637 define_has_prev(le, uint32_t)
638 define_has_prev(le, uint64_t)
639 
646 #define define_has_prev_sub(O, T) \
647  \
662 static inline bool has_prev_sub_##O##_##T(const uint8_t *src, uint64_t blklen, uint64_t blkpos, uint8_t bitstart, uint8_t bitend, uint64_t first, uint64_t *pos, T search) \
663 { \
664 HAS_PREV_START_BLOCK \
665 SUB_ITEM_VARS(T) \
666 HAS_SUB_END_BLOCK(O, T) \
667 }
668 
670 define_has_prev_sub(be, uint16_t)
671 define_has_prev_sub(be, uint32_t)
672 define_has_prev_sub(be, uint64_t)
674 define_has_prev_sub(le, uint16_t)
675 define_has_prev_sub(le, uint32_t)
676 define_has_prev_sub(le, uint64_t)
677 
678 // --- COLUMN MODE ---
679 
686 #define define_col_find_first(T) \
687  \
696 static inline uint64_t col_find_first_##T(const T *src, uint64_t *first, uint64_t *last, T search) \
697 { \
698 FIND_START_LOOP_BLOCK(T) \
699 COL_GET_ITEM_TASK \
700 FIND_FIRST_INNER_CHECK \
701 COL_GET_ITEM_TASK \
702 FIND_END_LOOP_BLOCK \
703 }
704 
709 
716 #define define_col_find_first_sub(T) \
717  \
728 static inline uint64_t col_find_first_sub_##T(const T *src, uint8_t bitstart, uint8_t bitend, uint64_t *first, uint64_t *last, T search) \
729 { \
730 SUB_ITEM_VARS(T) \
731 FIND_START_LOOP_BLOCK(T) \
732 COL_GET_SUB_ITEM_TASK \
733 FIND_FIRST_INNER_CHECK \
734 COL_GET_SUB_ITEM_TASK \
735 FIND_END_LOOP_BLOCK \
736 }
737 
742 
749 #define define_col_find_last(T) \
750  \
759 static inline uint64_t col_find_last_##T(const T *src, uint64_t *first, uint64_t *last, T search) \
760 { \
761 FIND_START_LOOP_BLOCK(T) \
762 COL_GET_ITEM_TASK \
763 FIND_LAST_INNER_CHECK \
764 COL_GET_ITEM_TASK \
765 FIND_END_LOOP_BLOCK \
766 }
767 
772 
779 #define define_col_find_last_sub(T) \
780  \
791 static inline uint64_t col_find_last_sub_##T(const T *src, uint8_t bitstart, uint8_t bitend, uint64_t *first, uint64_t *last, T search) \
792 { \
793 SUB_ITEM_VARS(T) \
794 FIND_START_LOOP_BLOCK(T) \
795 COL_GET_SUB_ITEM_TASK \
796 FIND_LAST_INNER_CHECK \
797 COL_GET_SUB_ITEM_TASK \
798 FIND_END_LOOP_BLOCK \
799 }
800 
805 
811 #define define_col_has_next(T) \
812  \
823 static inline bool col_has_next_##T(const T *src, uint64_t *pos, uint64_t last, T search) \
824 { \
825 HAS_NEXT_START_BLOCK \
826 COL_HAS_END_BLOCK(T) \
827 }
828 
833 
839 #define define_col_has_next_sub(T) \
840  \
853 static inline bool col_has_next_sub_##T(const T *src, uint8_t bitstart, uint8_t bitend, uint64_t *pos, uint64_t last, T search) \
854 { \
855 HAS_NEXT_START_BLOCK \
856 SUB_ITEM_VARS(T) \
857 COL_HAS_SUB_END_BLOCK(T) \
858 }
859 
864 
870 #define define_col_has_prev(T) \
871  \
882 static inline bool col_has_prev_##T(const T *src, uint64_t first, uint64_t *pos, T search) \
883 { \
884 HAS_PREV_START_BLOCK \
885 COL_HAS_END_BLOCK(T) \
886 }
887 
892 
898 #define define_col_has_prev_sub(T) \
899  \
912 static inline bool col_has_prev_sub_##T(const T *src, uint8_t bitstart, uint8_t bitend, uint64_t first, uint64_t *pos, T search) \
913 { \
914 HAS_PREV_START_BLOCK \
915 SUB_ITEM_VARS(T) \
916 COL_HAS_SUB_END_BLOCK(T) \
917 }
918 
923 
924 // --- FILE ---
925 
926 static inline void parse_col_offset(mmfile_t *mf)
927 {
928  uint8_t i;
929  uint64_t b = 0;
930  mf->index[0] = mf->doffset;
931  for (i = 0; i < mf->ncols; i++)
932  {
933  b += mf->ctbytes[i];
934  }
935  if (b == 0)
936  {
937  return;
938  }
939  mf->nrows = (mf->dlength / b);
940  for (i = 1; i < mf->ncols; i++)
941  {
942  b = (mf->nrows * mf->ctbytes[(i - 1)]);
943  mf->index[i] = mf->index[(i - 1)] + b + ((8 - (b & 7)) & 7); // account for 8-byte padding
944  }
945 }
946 
947 static inline void parse_info_binsrc(mmfile_t *mf)
948 {
949  const uint8_t *tp = (const uint8_t *)(mf->src + 8);
950  mf->ncols = *tp++;
951  mf->doffset = (uint64_t)9 + mf->ncols + ((8 - ((mf->ncols + 1) & 7)) & 7); // account for 8-byte padding
952  const uint64_t *op = (const uint64_t *)(mf->src + mf->doffset);
953  mf->nrows = *op++;
954  uint8_t i;
955  for (i = 0; i < mf->ncols; i++)
956  {
957  mf->ctbytes[i] = *tp++;
958  mf->index[i] = *op++;
959  }
960  mf->doffset += ((mf->ncols + 1) * 8); // skip column offsets section
961  mf->dlength -= mf->doffset;
962 }
963 
964 static inline void parse_info_arrow(mmfile_t *mf)
965 {
966  mf->doffset = (uint64_t)(*((const uint32_t *)(mf->src + 9))) + 13; // skip metadata
967  mf->doffset += (uint64_t)(*((const uint32_t *)(mf->src + mf->doffset)) + 4); // skip dictionary
968  mf->dlength -= mf->doffset;
969  uint64_t type = (*((const uint64_t *)(mf->src + mf->size - 8)));
970  if ((type & 0xffffffffffff0000) == 0x31574f5252410000) // magic number "ARROW1" in LE
971  {
972  mf->dlength -= (uint64_t)(*((const uint32_t *)(mf->src + mf->size - 10))) + 10; // remove footer
973  }
974 }
975 
976 static inline void parse_info_feather(mmfile_t *mf)
977 {
978  mf->doffset = 8;
979  mf->dlength -= mf->doffset;
980  uint32_t type = (*((const uint32_t *)(mf->src + mf->size - 4)));
981  if (type == 0x31414546) // magic number "FEA1" in LE
982  {
983  mf->dlength -= (uint64_t)(*((const uint32_t *)(mf->src + mf->size - 8))) + 8; // remove metadata
984  }
985 }
986 
995 static inline void mmap_binfile(const char *file, mmfile_t *mf)
996 {
997  mf->src = (uint8_t*)MAP_FAILED; // NOLINT
998  mf->fd = -1;
999  mf->size = 0;
1000  mf->doffset = 0;
1001  mf->dlength = 0;
1002  mf->nrows = 0;
1003  struct stat statbuf;
1004  if (((mf->fd = open(file, O_RDONLY)) < 0) || (fstat(mf->fd, &statbuf) < 0))
1005  {
1006  return;
1007  }
1008  mf->size = (uint64_t)statbuf.st_size;
1009  mf->src = (uint8_t*)mmap(0, mf->size, PROT_READ, MAP_PRIVATE, mf->fd, 0);
1010  mf->dlength = mf->size;
1011  if (mf->size < 28)
1012  {
1013  return;
1014  }
1015  uint64_t type = (*((const uint64_t *)(mf->src)));
1016  switch (type)
1017  {
1018  // Custom binsearch format
1019  case 0x00314352534e4942: // magic number "BINSRC1" in LE
1020  parse_info_binsrc(mf);
1021  return;
1022  // Basic support for Apache Arrow File format with a single RecordBatch.
1023  case 0x000031574f525241: // magic number "ARROW1" in LE
1024  parse_info_arrow(mf);
1025  break;
1026  // Basic support for Feather File format.
1027  case 0x0000000031414546: // magic number "FEA1" in LE
1028  parse_info_feather(mf);
1029  break;
1030  }
1031  parse_col_offset(mf);
1032 }
1033 
1042 static inline int munmap_binfile(mmfile_t mf)
1043 {
1044  int err = munmap(mf.src, mf.size);
1045  if (err != 0)
1046  {
1047  return err;
1048  }
1049  return close(mf.fd);
1050 }
1051 
1052 #endif // VARIANTKEY_BINSEARCH_H
uint64_t nrows
Number of rows.
Definition: binsearch.h:236
Definition: binsearch.h:229
#define define_has_prev_sub(O, T)
Definition: binsearch.h:646
int fd
File descriptor.
Definition: binsearch.h:232
#define define_col_has_next(T)
Definition: binsearch.h:811
struct mmfile_t mmfile_t
uint8_t * src
Pointer to the memory map.
Definition: binsearch.h:231
#define define_col_find_first(T)
Definition: binsearch.h:686
#define define_col_has_next_sub(T)
Definition: binsearch.h:839
#define define_has_next_sub(O, T)
Definition: binsearch.h:573
static void mmap_binfile(const char *file, mmfile_t *mf)
Definition: binsearch.h:995
#define define_find_first_sub(O, T)
Definition: binsearch.h:422
#define define_find_first(O, T)
Definition: binsearch.h:385
uint64_t doffset
Offset to the beginning of the data block (address of the first byte of the first item in the first c...
Definition: binsearch.h:234
uint64_t dlength
Length in bytes of the data block.
Definition: binsearch.h:235
uint64_t size
File size in bytes.
Definition: binsearch.h:233
#define define_get_src_offset(T)
Definition: binsearch.h:273
#define define_col_find_last_sub(T)
Definition: binsearch.h:779
uint8_t ctbytes[256]
Number of bytes per column type (i.e. 1 for uint8_t, 2 for uint16_t, 4 for uint32_t, 8 for uint64_t). - THIS MUST BE MANUALLY SET EXCEPT FOR THE "BINSRC1" FORMAT.
Definition: binsearch.h:238
#define MAXCOLS
Maximum number of columns indexable.
Definition: binsearch.h:192
uint8_t ncols
Number of columns - THIS MUST BE MANUALLY SET EXCEPT FOR THE "BINSRC1" FORMAT.
Definition: binsearch.h:237
#define define_col_find_first_sub(T)
Definition: binsearch.h:716
uint64_t index[256]
Index of the offsets to the beginning of each column.
Definition: binsearch.h:239
#define define_col_has_prev_sub(T)
Definition: binsearch.h:898
#define define_has_next(O, T)
Definition: binsearch.h:538
#define define_col_find_last(T)
Definition: binsearch.h:749
static int munmap_binfile(mmfile_t mf)
Definition: binsearch.h:1042
#define define_bytes_to(O, T)
Definition: binsearch.h:248
#define define_col_has_prev(T)
Definition: binsearch.h:870
static void parse_info_arrow(mmfile_t *mf)
Definition: binsearch.h:964
#define define_has_prev(O, T)
Definition: binsearch.h:611
static void parse_col_offset(mmfile_t *mf)
Definition: binsearch.h:926
#define define_find_last(O, T)
Definition: binsearch.h:462
static void parse_info_binsrc(mmfile_t *mf)
Definition: binsearch.h:947
static void parse_info_feather(mmfile_t *mf)
Definition: binsearch.h:976
#define define_find_last_sub(O, T)
Definition: binsearch.h:499