|
10 | 10 | #include <cpp/memory.h> // @manual |
11 | 11 | #else |
12 | 12 | #include "common/hs/util/cpp/memory.h" |
| 13 | +#include "justknobs/JustKnobProxy.h" |
13 | 14 | #endif |
14 | 15 | #include <glean/rts/ownership/uset.h> |
15 | 16 | #include "glean/rocksdb/database-impl.h" |
@@ -73,6 +74,17 @@ DatabaseImpl::loadOwnershipDerivedCounters() { |
73 | 74 |
|
74 | 75 | namespace { |
75 | 76 |
|
| 77 | +// Helper to serialize UnitId/UsetId based on format version |
| 78 | +rocksdb::Slice |
| 79 | +toSliceForFormat(binary::Output& out, uint64_t id, uint32_t format_version) { |
| 80 | + if (format_version == OWNERSHIP_FORMAT_VERSION_32BIT) { |
| 81 | + out.fixed(static_cast<uint32_t>(id)); |
| 82 | + } else { |
| 83 | + out.fixed(id); |
| 84 | + } |
| 85 | + return slice(out); |
| 86 | +} |
| 87 | + |
76 | 88 | void putOwnerSet( |
77 | 89 | ContainerImpl& container, |
78 | 90 | rocksdb::WriteBatch& batch, |
@@ -272,10 +284,12 @@ void DatabaseImpl::addOwnership(const std::vector<OwnershipSet>& ownership) { |
272 | 284 | touched.push_back(unit_id); |
273 | 285 | } else { |
274 | 286 | unit_id = first_unit_id + ownership_unit_counters.size() + new_count; |
| 287 | + // Write UnitId in format based on ownership_format_version |
| 288 | + binary::Output unitIdOut; |
275 | 289 | check(batch.Put( |
276 | 290 | container_.family(Family::ownershipUnits), |
277 | 291 | slice(set.unit), |
278 | | - toSlice(unit_id))); |
| 292 | + toSliceForFormat(unitIdOut, unit_id, ownership_format_version))); |
279 | 293 | EncodedNat key(unit_id); |
280 | 294 | check(batch.Put( |
281 | 295 | container_.family(Family::ownershipUnitIds), |
@@ -907,6 +921,17 @@ std::optional<UsetId> DatabaseImpl::FactOwnerCache::getOwner( |
907 | 921 | } |
908 | 922 |
|
909 | 923 | void DatabaseImpl::FactOwnerCache::prepare(ContainerImpl& container) { |
| 924 | + // Static function - need to check gatekeeper for format |
| 925 | +#ifndef OSS |
| 926 | + static facebook::jk::BooleanKnob use64BitOwnership( |
| 927 | + "glean/ownership:64_bit_ids"); |
| 928 | + uint32_t format_version = use64BitOwnership() |
| 929 | + ? OWNERSHIP_FORMAT_VERSION_64BIT |
| 930 | + : OWNERSHIP_FORMAT_VERSION_32BIT; |
| 931 | +#else |
| 932 | + uint32_t format_version = OWNERSHIP_FORMAT_VERSION_32BIT; |
| 933 | +#endif |
| 934 | + |
910 | 935 | auto t = makeAutoTimer("prepareFactOwnerCache"); |
911 | 936 |
|
912 | 937 | std::unique_ptr<rocksdb::Iterator> iter(container.db->NewIterator( |
@@ -934,7 +959,18 @@ void DatabaseImpl::FactOwnerCache::prepare(ContainerImpl& container) { |
934 | 959 | index.push_back(HAS_PAGE); |
935 | 960 | binary::Output out; |
936 | 961 | out.bytes(ids.data(), ids.size() * sizeof(uint16_t)); |
937 | | - out.bytes(sets.data(), sets.size() * sizeof(UsetId)); |
| 962 | + // Write UsetIds in format based on format_version |
| 963 | + if (format_version == OWNERSHIP_FORMAT_VERSION_32BIT) { |
| 964 | + // Write 32-bit UsetIds |
| 965 | + std::vector<uint32_t> sets32(sets.size()); |
| 966 | + for (size_t i = 0; i < sets.size(); i++) { |
| 967 | + sets32[i] = static_cast<uint32_t>(sets[i]); |
| 968 | + } |
| 969 | + out.bytes(sets32.data(), sets32.size() * sizeof(uint32_t)); |
| 970 | + } else { |
| 971 | + // Write 64-bit UsetIds |
| 972 | + out.bytes(sets.data(), sets.size() * sizeof(UsetId)); |
| 973 | + } |
938 | 974 | batch.Put( |
939 | 975 | container.family(Family::factOwnerPages), |
940 | 976 | toSlice(prefix), |
@@ -980,19 +1016,39 @@ void DatabaseImpl::FactOwnerCache::prepare(ContainerImpl& container) { |
980 | 1016 | // write the last page |
981 | 1017 | writePage(); |
982 | 1018 |
|
983 | | - batch.Put( |
984 | | - container.family(Family::factOwnerPages), |
985 | | - INDEX_KEY, |
986 | | - slice( |
987 | | - folly::ByteRange( |
988 | | - reinterpret_cast<const uint8_t*>(index.data()), |
989 | | - index.size() * sizeof(UsetId)))); |
| 1019 | + // Write index in format based on format_version |
| 1020 | + if (format_version == OWNERSHIP_FORMAT_VERSION_32BIT) { |
| 1021 | + // Write 32-bit index entries |
| 1022 | + std::vector<uint32_t> index32(index.size()); |
| 1023 | + if (!index.empty()) { |
| 1024 | + for (size_t i = 0; i < index.size(); i++) { |
| 1025 | + index32[i] = static_cast<uint32_t>(index[i]); |
| 1026 | + } |
| 1027 | + } |
| 1028 | + batch.Put( |
| 1029 | + container.family(Family::factOwnerPages), |
| 1030 | + INDEX_KEY, |
| 1031 | + slice( |
| 1032 | + folly::ByteRange( |
| 1033 | + reinterpret_cast<const uint8_t*>(index32.data()), |
| 1034 | + index32.size() * sizeof(uint32_t)))); |
| 1035 | + } else { |
| 1036 | + // Write 64-bit index entries |
| 1037 | + batch.Put( |
| 1038 | + container.family(Family::factOwnerPages), |
| 1039 | + INDEX_KEY, |
| 1040 | + slice( |
| 1041 | + folly::ByteRange( |
| 1042 | + reinterpret_cast<const uint8_t*>(index.data()), |
| 1043 | + index.size() * sizeof(UsetId)))); |
| 1044 | + } |
990 | 1045 |
|
991 | 1046 | t.logFormat( |
992 | | - "{} index entries, {} populated, {} orphans", |
| 1047 | + "{} index entries, {} populated, {} orphans (format: {})", |
993 | 1048 | index.size(), |
994 | 1049 | populated, |
995 | | - orphaned); |
| 1050 | + orphaned, |
| 1051 | + format_version == OWNERSHIP_FORMAT_VERSION_32BIT ? "32-bit" : "64-bit"); |
996 | 1052 |
|
997 | 1053 | // record the number of orphaned facts, this will be fetched by ownershipStats |
998 | 1054 | batch.Put( |
@@ -1110,16 +1166,38 @@ void DatabaseImpl::addDefineOwnership(DefineOwnership& def) { |
1110 | 1166 | pred.new_ids_.size() * |
1111 | 1167 | sizeof(std::remove_reference< |
1112 | 1168 | decltype(pred.new_ids_)>::type::value_type)); |
1113 | | - val.bytes( |
1114 | | - pred.owners_.data(), |
1115 | | - pred.owners_.size() * |
1116 | | - sizeof(std::remove_reference< |
1117 | | - decltype(pred.owners_)>::type::value_type)); |
1118 | | - val.bytes( |
1119 | | - pred.new_owners_.data(), |
1120 | | - pred.new_owners_.size() * |
1121 | | - sizeof(std::remove_reference< |
1122 | | - decltype(pred.new_owners_)>::type::value_type)); |
| 1169 | + |
| 1170 | + // Write owners in format based on ownership_format_version |
| 1171 | + if (ownership_format_version == OWNERSHIP_FORMAT_VERSION_32BIT) { |
| 1172 | + // 32-bit UsetId format |
| 1173 | + std::vector<uint32_t> owners32(pred.owners_.size()); |
| 1174 | + if (!pred.owners_.empty()) { |
| 1175 | + for (size_t i = 0; i < pred.owners_.size(); i++) { |
| 1176 | + owners32[i] = static_cast<uint32_t>(pred.owners_[i]); |
| 1177 | + } |
| 1178 | + } |
| 1179 | + val.bytes(owners32.data(), owners32.size() * sizeof(uint32_t)); |
| 1180 | + |
| 1181 | + std::vector<uint32_t> new_owners32(pred.new_owners_.size()); |
| 1182 | + if (!pred.new_owners_.empty()) { |
| 1183 | + for (size_t i = 0; i < pred.new_owners_.size(); i++) { |
| 1184 | + new_owners32[i] = static_cast<uint32_t>(pred.new_owners_[i]); |
| 1185 | + } |
| 1186 | + } |
| 1187 | + val.bytes(new_owners32.data(), new_owners32.size() * sizeof(uint32_t)); |
| 1188 | + } else { |
| 1189 | + // 64-bit UsetId format |
| 1190 | + val.bytes( |
| 1191 | + pred.owners_.data(), |
| 1192 | + pred.owners_.size() * |
| 1193 | + sizeof(std::remove_reference< |
| 1194 | + decltype(pred.owners_)>::type::value_type)); |
| 1195 | + val.bytes( |
| 1196 | + pred.new_owners_.data(), |
| 1197 | + pred.new_owners_.size() * |
| 1198 | + sizeof(std::remove_reference< |
| 1199 | + decltype(pred.new_owners_)>::type::value_type)); |
| 1200 | + } |
1123 | 1201 |
|
1124 | 1202 | check(batch.Put( |
1125 | 1203 | container_.family(Family::ownershipDerivedRaw), |
|
0 commit comments