9 #ifndef INCLUDE_ROARING_64_MAP_HH_
10 #define INCLUDE_ROARING_64_MAP_HH_
18 #include <initializer_list>
34 class Roaring64MapSetBitBiDirectionalIterator;
38 typedef Roaring64MapSetBitBiDirectionalIterator
116 for (
size_t i = 0; i < n; i++) {
117 ans.
add(va_arg(vl, uint64_t));
129 ans.
addMany(l.size(), l.begin());
136 void add(uint32_t x) { lookupOrCreateInner(0).
add(x); }
141 void add(uint64_t x) { lookupOrCreateInner(highBytes(x)).
add(lowBytes(x)); }
156 return lookupOrCreateInner(highBytes(x)).
addChecked(lowBytes(x));
183 uint32_t start_high = highBytes(min);
184 uint32_t start_low = lowBytes(min);
185 uint32_t end_high = highBytes(max);
186 uint32_t end_low = lowBytes(max);
190 const uint32_t uint32_max = (std::numeric_limits<uint32_t>::max)();
195 auto current_iter = ensureRangePopulated(start_high, end_high);
199 if (start_high == end_high) {
200 auto &bitmap = current_iter->second;
201 bitmap.addRangeClosed(start_low, end_low);
212 auto num_intermediate_bitmaps = end_high - start_high - 1;
216 auto &bitmap = current_iter->second;
217 bitmap.addRangeClosed(start_low, uint32_max);
222 if (num_intermediate_bitmaps != 0) {
223 auto &first_intermediate = current_iter->second;
224 first_intermediate.addRangeClosed(0, uint32_max);
228 for (uint32_t i = 1; i != num_intermediate_bitmaps; ++i) {
229 auto &next_intermediate = current_iter->second;
230 next_intermediate = first_intermediate;
236 auto &bitmap = current_iter->second;
237 bitmap.addRangeClosed(0, end_low);
243 void addMany(
size_t n_args,
const uint32_t *vals) {
244 lookupOrCreateInner(0).
addMany(n_args, vals);
250 void addMany(
size_t n_args,
const uint64_t *vals) {
253 Roaring *last_inner_bitmap =
nullptr;
254 uint32_t last_value_high = 0;
256 for (
size_t lcv = 0; lcv < n_args; lcv++) {
257 auto value = vals[lcv];
258 auto value_high = highBytes(value);
259 auto value_low = lowBytes(value);
260 if (last_inner_bitmap ==
nullptr || value_high != last_value_high) {
261 last_inner_bitmap = &lookupOrCreateInner(value_high);
262 last_value_high = value_high;
265 last_inner_bitmap->
addBulk(last_bulk_context, value_low);
273 auto iter = roarings.begin();
276 if (iter == roarings.end() || iter->first != 0) {
279 auto &bitmap = iter->second;
288 auto iter = roarings.find(highBytes(x));
289 if (iter == roarings.end()) {
292 auto &bitmap = iter->second;
293 bitmap.remove(lowBytes(x));
303 auto iter = roarings.begin();
306 if (iter == roarings.end() || iter->first != 0) {
309 auto &bitmap = iter->second;
310 if (!bitmap.removeChecked(x)) {
323 auto iter = roarings.find(highBytes(x));
324 if (iter == roarings.end()) {
327 auto &bitmap = iter->second;
328 if (!bitmap.removeChecked(lowBytes(x))) {
349 auto iter = roarings.begin();
353 if (iter == roarings.end() || iter->first != 0) {
356 auto &bitmap = iter->second;
357 bitmap.removeRangeClosed(min, max);
368 uint32_t start_high = highBytes(min);
369 uint32_t start_low = lowBytes(min);
370 uint32_t end_high = highBytes(max);
371 uint32_t end_low = lowBytes(max);
375 const uint32_t uint32_max = (std::numeric_limits<uint32_t>::max)();
380 if (roarings.empty() || end_high < roarings.cbegin()->first ||
381 start_high > (roarings.crbegin())->first) {
389 auto start_iter = roarings.lower_bound(start_high);
392 auto end_iter = roarings.lower_bound(end_high);
413 if (start_iter->first == start_high) {
414 auto &start_inner = start_iter->second;
416 if (start_iter == end_iter) {
417 start_inner.removeRangeClosed(start_low, end_low);
418 eraseIfEmpty(start_iter);
423 start_inner.removeRangeClosed(start_low, uint32_max);
426 auto temp = start_iter++;
431 roarings.erase(start_iter, end_iter);
434 if (end_iter != roarings.end() && end_iter->first == end_high) {
435 auto &end_inner = end_iter->second;
436 end_inner.removeRangeClosed(0, end_low);
437 eraseIfEmpty(end_iter);
450 for (
auto roaring_iter = roarings.crbegin();
451 roaring_iter != roarings.crend(); ++roaring_iter) {
452 if (!roaring_iter->second.isEmpty()) {
453 return uniteBytes(roaring_iter->first,
454 roaring_iter->second.maximum());
459 return (std::numeric_limits<uint64_t>::min)();
466 for (
auto roaring_iter = roarings.cbegin();
467 roaring_iter != roarings.cend(); ++roaring_iter) {
468 if (!roaring_iter->second.isEmpty()) {
469 return uniteBytes(roaring_iter->first,
470 roaring_iter->second.minimum());
475 return (std::numeric_limits<uint64_t>::max)();
482 auto iter = roarings.find(0);
483 if (iter == roarings.end()) {
486 return iter->second.contains(x);
489 auto iter = roarings.find(highBytes(x));
490 if (iter == roarings.end()) {
493 return iter->second.contains(lowBytes(x));
507 if (
this == &other) {
526 decltype(roarings.begin()) self_next;
527 for (
auto self_iter = roarings.begin(); self_iter != roarings.end();
528 self_iter = self_next) {
531 self_next = std::next(self_iter);
533 auto self_key = self_iter->first;
534 auto &self_bitmap = self_iter->second;
536 auto other_iter = other.roarings.find(self_key);
537 if (other_iter == other.roarings.end()) {
541 roarings.erase(self_iter);
548 const auto &other_bitmap = other_iter->second;
549 self_bitmap &= other_bitmap;
550 if (self_bitmap.isEmpty()) {
552 roarings.erase(self_iter);
564 if (
this == &other) {
585 auto self_iter = roarings.begin();
586 auto other_iter = other.roarings.cbegin();
588 while (self_iter != roarings.end() &&
589 other_iter != other.roarings.cend()) {
590 auto self_key = self_iter->first;
591 auto other_key = other_iter->first;
592 if (self_key < other_key) {
595 self_iter = roarings.lower_bound(other_key);
599 if (self_key > other_key) {
602 other_iter = other.roarings.lower_bound(self_key);
609 auto &self_bitmap = self_iter->second;
610 const auto &other_bitmap = other_iter->second;
611 self_bitmap -= other_bitmap;
613 if (self_bitmap.isEmpty()) {
615 self_iter = roarings.erase(self_iter);
632 if (
this == &other) {
650 for (
const auto &other_entry : other.roarings) {
651 const auto &other_bitmap = other_entry.second;
656 auto insert_result = roarings.insert(other_entry);
657 auto self_iter = insert_result.first;
658 auto insert_happened = insert_result.second;
659 auto &self_bitmap = self_iter->second;
661 if (insert_happened) {
667 self_bitmap.setCopyOnWrite(copyOnWrite);
674 self_bitmap |= other_bitmap;
684 if (
this == &other) {
704 for (
const auto &other_entry : other.roarings) {
705 const auto &other_bitmap = other_entry.second;
710 auto insert_result = roarings.insert(other_entry);
711 auto self_iter = insert_result.first;
712 auto insert_happened = insert_result.second;
713 auto &self_bitmap = self_iter->second;
715 if (insert_happened) {
721 self_bitmap.setCopyOnWrite(copyOnWrite);
728 self_bitmap ^= other_bitmap;
730 if (self_bitmap.isEmpty()) {
732 roarings.erase(self_iter);
751 #if ROARING_EXCEPTIONS
752 throw std::length_error(
753 "bitmap is full, cardinality is 2^64, "
754 "unable to represent in a 64-bit integer");
757 "bitmap is full, cardinality is 2^64, "
758 "unable to represent in a 64-bit integer");
761 return std::accumulate(
762 roarings.cbegin(), roarings.cend(), (uint64_t)0,
763 [](uint64_t previous,
764 const std::pair<const uint32_t, Roaring> &map_entry) {
765 return previous + map_entry.second.cardinality();
774 roarings.cbegin(), roarings.cend(),
775 [](
const std::pair<const uint32_t, Roaring> &map_entry) {
776 return map_entry.second.isEmpty();
788 return roarings.size() ==
789 ((uint64_t)(std::numeric_limits<uint32_t>::max)()) + 1
790 ? std::all_of(roarings.cbegin(), roarings.cend(),
791 [](
const std::pair<const uint32_t, Roaring>
792 &roaring_map_entry) {
793 return roaring_map_entry.second.isFull();
802 for (
const auto &map_entry : roarings) {
803 if (map_entry.second.isEmpty()) {
806 auto roaring_iter = r.roarings.find(map_entry.first);
807 if (roaring_iter == r.roarings.cend())
809 else if (!map_entry.second.isSubset(roaring_iter->second))
833 (void)std::accumulate(
834 roarings.cbegin(), roarings.cend(), ans,
835 [](uint64_t *previous,
836 const std::pair<const uint32_t, Roaring> &map_entry) {
837 for (uint32_t low_bits : map_entry.second)
838 *previous++ = uniteBytes(map_entry.first, low_bits);
849 auto lhs_iter = roarings.cbegin();
850 auto lhs_cend = roarings.cend();
851 auto rhs_iter = r.roarings.cbegin();
852 auto rhs_cend = r.roarings.cend();
853 while (lhs_iter != lhs_cend && rhs_iter != rhs_cend) {
854 auto lhs_key = lhs_iter->first, rhs_key = rhs_iter->first;
855 const auto &lhs_map = lhs_iter->second, &rhs_map = rhs_iter->second;
856 if (lhs_map.isEmpty()) {
860 if (rhs_map.isEmpty()) {
864 if (!(lhs_key == rhs_key)) {
867 if (!(lhs_map == rhs_map)) {
873 while (lhs_iter != lhs_cend) {
874 if (!lhs_iter->second.isEmpty()) {
879 while (rhs_iter != rhs_cend) {
880 if (!rhs_iter->second.isEmpty()) {
892 void flip(uint64_t min, uint64_t max) {
904 auto iter = roarings.begin();
908 if (iter == roarings.end() || iter->first != 0) {
909 iter = roarings.emplace_hint(iter, std::piecewise_construct,
910 std::forward_as_tuple(0),
911 std::forward_as_tuple());
912 auto &bitmap = iter->second;
913 bitmap.setCopyOnWrite(copyOnWrite);
915 auto &bitmap = iter->second;
916 bitmap.flipClosed(min, max);
928 uint32_t start_high = highBytes(min);
929 uint32_t start_low = lowBytes(min);
930 uint32_t end_high = highBytes(max);
931 uint32_t end_low = lowBytes(max);
935 const uint32_t uint32_max = (std::numeric_limits<uint32_t>::max)();
940 auto current_iter = ensureRangePopulated(start_high, end_high);
944 if (start_high == end_high) {
945 auto &bitmap = current_iter->second;
946 bitmap.flipClosed(start_low, end_low);
947 eraseIfEmpty(current_iter);
959 auto num_intermediate_bitmaps = end_high - start_high - 1;
963 auto &bitmap = current_iter->second;
964 bitmap.flipClosed(start_low, uint32_max);
965 auto temp = current_iter++;
970 for (uint32_t i = 0; i != num_intermediate_bitmaps; ++i) {
971 auto &bitmap = current_iter->second;
972 bitmap.flipClosed(0, uint32_max);
973 auto temp = current_iter++;
978 auto &bitmap = current_iter->second;
979 bitmap.flipClosed(0, end_low);
980 eraseIfEmpty(current_iter);
988 return std::accumulate(
989 roarings.begin(), roarings.end(),
true,
990 [](
bool previous, std::pair<const uint32_t, Roaring> &map_entry) {
991 return map_entry.second.removeRunCompression() && previous;
1002 return std::accumulate(
1003 roarings.begin(), roarings.end(),
true,
1004 [](
bool previous, std::pair<const uint32_t, Roaring> &map_entry) {
1005 return map_entry.second.runOptimize() && previous;
1014 size_t savedBytes = 0;
1015 auto iter = roarings.begin();
1016 while (iter != roarings.cend()) {
1017 if (iter->second.isEmpty()) {
1020 roarings.erase(iter++);
1022 savedBytes += iter->second.shrinkToFit();
1040 void iterate(api::roaring_iterator64 iterator,
void *ptr)
const {
1041 for (
const auto &map_entry : roarings) {
1042 bool should_continue =
1044 uint64_t(map_entry.first) << 32, ptr);
1045 if (!should_continue) {
1058 for (
const auto &map_entry : roarings) {
1059 auto key = map_entry.first;
1060 const auto &bitmap = map_entry.second;
1062 uint64_t sub_cardinality = bitmap.cardinality();
1063 if (
rank < sub_cardinality) {
1067 if (!bitmap.select((uint32_t)
rank, &low_bytes)) {
1069 "Logic error: bitmap.select() "
1070 "returned false despite rank < cardinality()");
1072 *element = uniteBytes(key, low_bytes);
1075 rank -= sub_cardinality;
1084 uint64_t result = 0;
1089 auto end = roarings.lower_bound(highBytes(x));
1090 if (
end != roarings.cend() &&
end->first == highBytes(x)) {
1091 result +=
end->second.rank(lowBytes(x));
1093 for (
auto iter = roarings.cbegin(); iter !=
end; ++iter) {
1094 result += iter->second.cardinality();
1108 auto roaring_destination = roarings.find(highBytes(x));
1109 if (roaring_destination != roarings.cend()) {
1110 for (
auto roaring_iter = roarings.cbegin();
1111 roaring_iter != roaring_destination; ++roaring_iter) {
1112 index += roaring_iter->second.cardinality();
1114 auto low_idx = roaring_destination->second.getIndex(lowBytes(x));
1115 if (low_idx < 0)
return -1;
1131 size_t write(
char *buf,
bool portable =
true)
const {
1132 const char *orig = buf;
1134 uint64_t map_size = roarings.size();
1135 std::memcpy(buf, &map_size,
sizeof(uint64_t));
1136 buf +=
sizeof(uint64_t);
1137 std::for_each(roarings.cbegin(), roarings.cend(),
1139 const std::pair<const uint32_t, Roaring> &map_entry) {
1141 std::memcpy(buf, &map_entry.first, sizeof(uint32_t));
1145 buf += sizeof(uint32_t);
1147 buf += map_entry.second.write(buf, portable);
1168 std::memcpy(&map_size, buf,
sizeof(uint64_t));
1169 buf +=
sizeof(uint64_t);
1170 for (uint64_t lcv = 0; lcv < map_size; lcv++) {
1173 std::memcpy(&key, buf,
sizeof(uint32_t));
1176 buf +=
sizeof(uint32_t);
1181 result.emplaceOrInsert(key, std::move(read_var));
1194 if (maxbytes <
sizeof(uint64_t)) {
1199 std::memcpy(&map_size, buf,
sizeof(uint64_t));
1200 buf +=
sizeof(uint64_t);
1201 maxbytes -=
sizeof(uint64_t);
1202 for (uint64_t lcv = 0; lcv < map_size; lcv++) {
1203 if (maxbytes <
sizeof(uint32_t)) {
1207 std::memcpy(&key, buf,
sizeof(uint32_t));
1210 buf +=
sizeof(uint32_t);
1211 maxbytes -=
sizeof(uint32_t);
1218 result.emplaceOrInsert(key, std::move(read_var));
1233 return std::accumulate(
1234 roarings.cbegin(), roarings.cend(),
1235 sizeof(uint64_t) + roarings.size() *
sizeof(uint32_t),
1236 [=](
size_t previous,
1237 const std::pair<const uint32_t, Roaring> &map_entry) {
1239 return previous + map_entry.second.getSizeInBytes(portable);
1245 const size_t metadata_size =
sizeof(size_t) +
sizeof(uint32_t);
1251 memcpy(&map_size, buf,
sizeof(uint64_t));
1252 buf +=
sizeof(uint64_t);
1254 for (uint64_t lcv = 0; lcv < map_size; lcv++) {
1256 while (((uintptr_t)buf + metadata_size) % 32 != 0) buf++;
1260 memcpy(&len, buf,
sizeof(
size_t));
1261 buf +=
sizeof(size_t);
1265 memcpy(&key, buf,
sizeof(uint32_t));
1266 buf +=
sizeof(uint32_t);
1270 result.emplaceOrInsert(key,
read);
1282 std::memcpy(&map_size, buf,
sizeof(uint64_t));
1283 buf +=
sizeof(uint64_t);
1284 for (uint64_t lcv = 0; lcv < map_size; lcv++) {
1287 std::memcpy(&key, buf,
sizeof(uint32_t));
1288 buf +=
sizeof(uint32_t);
1293 result.emplaceOrInsert(key, std::move(read_var));
1309 const size_t metadata_size =
sizeof(size_t) +
sizeof(uint32_t);
1312 uint64_t map_size = roarings.size();
1313 memcpy(buf, &map_size,
sizeof(uint64_t));
1314 buf +=
sizeof(uint64_t);
1316 for (
auto &map_entry : roarings) {
1317 size_t frozenSizeInBytes = map_entry.second.getFrozenSizeInBytes();
1320 while (((uintptr_t)buf + metadata_size) % 32 != 0) buf++;
1323 memcpy(buf, &frozenSizeInBytes,
sizeof(
size_t));
1324 buf +=
sizeof(size_t);
1327 memcpy(buf, &map_entry.first,
sizeof(uint32_t));
1328 buf +=
sizeof(uint32_t);
1331 map_entry.second.writeFrozen(buf);
1332 buf += map_entry.second.getFrozenSizeInBytes();
1338 const size_t metadata_size =
sizeof(size_t) +
sizeof(uint32_t);
1342 ret +=
sizeof(uint64_t);
1344 for (
auto &map_entry : roarings) {
1346 while ((ret + metadata_size) % 32 != 0) ret++;
1347 ret += metadata_size;
1350 ret += map_entry.second.getFrozenSizeInBytes();
1396 if (copyOnWrite == val)
return;
1398 std::for_each(roarings.begin(), roarings.end(),
1399 [=](std::pair<const uint32_t, Roaring> &map_entry) {
1400 map_entry.second.setCopyOnWrite(val);
1409 auto sink = [](
const std::string &s) { fputs(s.c_str(), stdout); };
1419 auto sink = [&result](
const std::string &s) { result += s; };
1453 roarings_t::const_iterator iterator;
1454 roarings_t::const_iterator
end;
1458 auto pq_comp = [](
const pq_entry &lhs,
const pq_entry &rhs) {
1459 auto left_key = lhs.iterator->first;
1460 auto right_key = rhs.iterator->first;
1465 return left_key > right_key;
1469 std::priority_queue<pq_entry, std::vector<pq_entry>, decltype(pq_comp)>
1471 for (
size_t i = 0; i < n; ++i) {
1472 const auto &roarings = inputs[i]->roarings;
1473 if (roarings.begin() != roarings.end()) {
1474 pq.push({roarings.begin(), roarings.end()});
1480 std::vector<const roaring_bitmap_t *> group_bitmaps;
1498 while (!pq.empty()) {
1500 auto group_key = pq.top().iterator->first;
1507 group_bitmaps.
clear();
1508 while (!pq.empty()) {
1509 auto candidate_current_iter = pq.top().iterator;
1510 auto candidate_end_iter = pq.top().end;
1512 auto candidate_key = candidate_current_iter->first;
1513 const auto &candidate_bitmap = candidate_current_iter->second;
1520 if (candidate_key != group_key) {
1529 group_bitmaps.push_back(&candidate_bitmap.roaring);
1538 ++candidate_current_iter;
1539 if (candidate_current_iter != candidate_end_iter) {
1540 pq.push({candidate_current_iter, candidate_end_iter});
1546 group_bitmaps.data());
1549 result.roarings.insert(
1550 result.roarings.end(),
1551 std::make_pair(group_key,
Roaring(inner_result)));
1579 typedef std::map<uint32_t, Roaring> roarings_t;
1580 roarings_t roarings{};
1582 bool copyOnWrite{
false};
1583 static constexpr uint32_t highBytes(
const uint64_t in) {
1584 return uint32_t(in >> 32);
1586 static constexpr uint32_t lowBytes(
const uint64_t in) {
1587 return uint32_t(in);
1589 static constexpr uint64_t uniteBytes(
const uint32_t highBytes,
1590 const uint32_t lowBytes) {
1591 return (uint64_t(highBytes) << 32) | uint64_t(lowBytes);
1595 void emplaceOrInsert(
const uint32_t key,
const Roaring &value) {
1596 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20130322
1597 roarings.insert(std::make_pair(key, value));
1599 roarings.emplace(std::make_pair(key, value));
1603 void emplaceOrInsert(
const uint32_t key, Roaring &&value) {
1604 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20130322
1605 roarings.insert(std::make_pair(key, std::move(value)));
1607 roarings.emplace(key, std::move(value));
1616 Roaring &lookupOrCreateInner(uint32_t key) {
1617 auto &bitmap = roarings[key];
1618 bitmap.setCopyOnWrite(copyOnWrite);
1626 const std::function<
void(
const std::string &)> &sink)
const {
1632 const char *separator =
"";
1634 std::string callback_string;
1635 for (
const auto &entry : roarings) {
1636 auto high_bits = entry.first;
1637 const auto &bitmap = entry.second;
1638 for (
const auto low_bits : bitmap) {
1639 auto value = uniteBytes(high_bits, low_bits);
1640 snprintf(buffer,
sizeof(buffer),
"%" PRIu64, value);
1641 callback_string = separator;
1642 callback_string.append(buffer);
1643 sink(callback_string);
1656 roarings_t::iterator ensureRangePopulated(uint32_t start_high,
1657 uint32_t end_high) {
1658 if (start_high > end_high) {
1663 auto next_populated_iter = roarings.lower_bound(start_high);
1666 roarings_t::iterator start_iter{};
1667 for (uint64_t slot = start_high; slot <= end_high; ++slot) {
1668 roarings_t::iterator slot_iter;
1669 if (next_populated_iter != roarings.end() &&
1670 next_populated_iter->first == slot) {
1673 slot_iter = next_populated_iter++;
1680 slot_iter = roarings.emplace_hint(
1681 next_populated_iter, std::piecewise_construct,
1682 std::forward_as_tuple(uint32_t(slot)),
1683 std::forward_as_tuple());
1684 auto &bitmap = slot_iter->second;
1685 bitmap.setCopyOnWrite(copyOnWrite);
1690 if (slot == start_high) {
1691 start_iter = slot_iter;
1701 void eraseIfEmpty(roarings_t::iterator iter) {
1702 const auto &bitmap = iter->second;
1703 if (bitmap.isEmpty()) {
1704 roarings.erase(iter);
1724 bool exhausted =
false)
1725 : p(&parent.roarings) {
1726 if (exhausted || parent.roarings.empty()) {
1727 map_iter = p->cend();
1729 map_iter = parent.roarings.cbegin();
1731 while (!i.has_value) {
1733 if (map_iter == p->cend())
return;
1743 return Roaring64Map::uniteBytes(map_iter->first, i.current_value);
1747 if (map_iter == p->cend())
return false;
1748 if (o.map_iter == o.p->cend())
return true;
1753 if (o.map_iter == o.p->cend())
return true;
1754 if (map_iter == p->cend())
return false;
1755 return **
this <= *o;
1759 if (o.map_iter == o.p->cend())
return false;
1760 if (map_iter == p->cend())
return true;
1765 if (map_iter == p->cend())
return true;
1766 if (o.map_iter == o.p->cend())
return false;
1767 return **
this >= *o;
1772 while (!i.has_value) {
1774 if (map_iter == p->cend())
return *
this;
1783 while (!i.has_value) {
1785 if (map_iter == p->cend())
return orig;
1796 map_iter = p->lower_bound(Roaring64Map::highBytes(x));
1797 if (map_iter != p->cend()) {
1799 if (map_iter->first == Roaring64Map::highBytes(x)) {
1801 &i, Roaring64Map::lowBytes(x)))
1804 if (map_iter == p->cend())
return false;
1818 if (map_iter == p->cend()) {
1821 if (i.has_value)
return *
this;
1825 while (!i.has_value) {
1826 if (map_iter == p->cbegin())
return *
this;
1835 if (map_iter == p->cend()) {
1842 while (!i.has_value) {
1843 if (map_iter == p->cbegin())
return orig;
1851 if (map_iter == p->cend() && o.map_iter == o.p->cend())
return true;
1852 if (o.map_iter == o.p->cend())
return false;
1853 return **
this == *o;
1857 if (map_iter == p->cend() && o.map_iter == o.p->cend())
return false;
1858 if (o.map_iter == o.p->cend())
return true;
1859 return **
this != *o;
1863 const std::map<uint32_t, Roaring> *p{
nullptr};
1864 std::map<uint32_t, Roaring>::const_iterator
type_of_iterator operator++(int)
bool operator<(const type_of_iterator &o) const
type_of_iterator & operator--()
bool operator<=(const type_of_iterator &o) const
bool operator!=(const Roaring64MapSetBitBiDirectionalIterator &o) const
Roaring64MapSetBitBiDirectionalIterator(const Roaring64Map &parent, bool exhausted=false)
bool operator>(const type_of_iterator &o) const
CROARING_DEPRECATED bool move(const value_type &x)
value_type operator*() const
std::bidirectional_iterator_tag iterator_category
type_of_iterator operator--(int)
bool operator==(const Roaring64MapSetBitBiDirectionalIterator &o) const
Roaring64MapSetBitBiDirectionalIterator type_of_iterator
bool operator>=(const type_of_iterator &o) const
bool move_equalorlarger(const value_type &x)
type_of_iterator & operator++()
void addMany(size_t n_args, const uint32_t *vals)
bool removeRunCompression()
void flip(uint64_t min, uint64_t max)
friend class Roaring64MapSetBitBiDirectionalIterator
Roaring64Map(size_t n, const uint64_t *data)
uint64_t rank(uint64_t x) const
size_t getFrozenSizeInBytes() const
Roaring64Map operator-(const Roaring64Map &o) const
void flipClosed(uint32_t min, uint32_t max)
bool contains(uint32_t x) const
uint64_t cardinality() const
const_iterator end() const
bool contains(uint64_t x) const
Roaring64Map(size_t n, const uint32_t *data)
Roaring64Map & operator|=(const Roaring64Map &other)
Roaring64Map & operator=(std::initializer_list< uint64_t > l)
Roaring64Map & operator&=(const Roaring64Map &other)
std::string toString() const
Roaring64Map(const Roaring &r)
Roaring64Map & operator=(const Roaring64Map &r)=default
Roaring64MapSetBitBiDirectionalIterator const_iterator
bool operator==(const Roaring64Map &r) const
bool isSubset(const Roaring64Map &r) const
const_iterator begin() const
size_t write(char *buf, bool portable=true) const
void removeRangeClosed(uint64_t min, uint64_t max)
bool removeChecked(uint32_t x)
Roaring64Map operator|(const Roaring64Map &o) const
bool addChecked(uint64_t x)
void addRangeClosed(uint64_t min, uint64_t max)
bool getCopyOnWrite() const
Roaring64Map(Roaring &&r)
static Roaring64Map readSafe(const char *buf, size_t maxbytes)
static Roaring64Map fastunion(size_t n, const Roaring64Map **inputs)
Roaring64Map & operator^=(const Roaring64Map &other)
Roaring64Map(const Roaring64Map &r)=default
Roaring64Map operator^(const Roaring64Map &o) const
static const Roaring64Map frozenView(const char *buf)
static Roaring64Map read(const char *buf, bool portable=true)
void addMany(size_t n_args, const uint64_t *vals)
static Roaring64Map bitmapOfList(std::initializer_list< uint64_t > l)
void addRange(uint64_t min, uint64_t max)
Roaring64Map operator&(const Roaring64Map &o) const
static Roaring64Map bitmapOf(size_t n...)
bool removeChecked(uint64_t x)
Roaring64Map(roaring_bitmap_t *s)
Roaring64Map & operator-=(const Roaring64Map &other)
Roaring64MapSetBitBiDirectionalIterator const_bidirectional_iterator
void setCopyOnWrite(bool val)
Roaring64Map(Roaring64Map &&r) noexcept=default
void flipClosed(uint64_t min, uint64_t max)
void toUint64Array(uint64_t *ans) const
static const Roaring64Map portableDeserializeFrozen(const char *buf)
size_t getSizeInBytes(bool portable=true) const
void removeRange(uint64_t min, uint64_t max)
void iterate(api::roaring_iterator64 iterator, void *ptr) const
Roaring64Map & operator=(Roaring64Map &&r) noexcept=default
void removeRangeClosed(uint32_t min, uint32_t max)
void swap(Roaring64Map &r)
void addRangeClosed(uint32_t min, uint32_t max)
bool select(uint64_t rank, uint64_t *element) const
void writeFrozen(char *buf) const
Roaring64Map(std::initializer_list< uint64_t > l)
bool isStrictSubset(const Roaring64Map &r) const
bool addChecked(uint32_t x)
int64_t getIndex(uint64_t x) const
static Roaring readSafe(const char *buf, size_t maxbytes)
bool addChecked(uint32_t x) noexcept
void addRangeClosed(const uint32_t min, const uint32_t max) noexcept
static Roaring read(const char *buf, bool portable=true)
void add(uint32_t x) noexcept
void addBulk(BulkContext &context, uint32_t x) noexcept
void addMany(size_t n_args, const uint32_t *vals) noexcept
static const Roaring frozenView(const char *buf, size_t length)
static const Roaring portableDeserializeFrozen(const char *buf)
size_t getSizeInBytes(bool portable=true) const noexcept
Roaring64MapSetBitBiDirectionalIterator Roaring64MapSetBitForwardIterator
void roaring_iterator_init_last(const roaring_bitmap_t *r, roaring_uint32_iterator_t *newit)
roaring_bitmap_t * roaring_bitmap_or_many(size_t number, const roaring_bitmap_t **rs)
bool roaring_iterate64(const roaring_bitmap_t *r, roaring_iterator64 iterator, uint64_t high_bits, void *ptr)
void roaring_iterator_init(const roaring_bitmap_t *r, roaring_uint32_iterator_t *newit)
bool roaring_uint32_iterator_move_equalorlarger(roaring_uint32_iterator_t *it, uint32_t val)
bool roaring_uint32_iterator_previous(roaring_uint32_iterator_t *it)
struct roaring_bitmap_s roaring_bitmap_t
struct roaring_uint32_iterator_s roaring_uint32_iterator_t
bool roaring_uint32_iterator_advance(roaring_uint32_iterator_t *it)
#define ROARING_TERMINATE(_s)