1313// /
1414// / OnDiskGraphDB defines:
1515// /
16- // / - How the data are stored inside database, either as a standalone file, or
16+ // / - How the data is stored inside database, either as a standalone file, or
1717// / allocated inside a datapool.
1818// / - How references to other objects inside the same database is stored. They
1919// / are stored as internal references, instead of full hash value to save
@@ -90,7 +90,7 @@ static Error createCorruptObjectError(Expected<ArrayRef<uint8_t>> ID) {
9090
9191namespace {
9292
93- // / Trie record data: 8B , atomic<uint64_t>
93+ // / Trie record data: 8 bytes , atomic<uint64_t>
9494// / - 1-byte: StorageKind
9595// / - 7-bytes: DataStoreOffset (offset into referenced file)
9696class TrieRecord {
@@ -129,7 +129,7 @@ class TrieRecord {
129129 }
130130
131131 enum Limits : int64_t {
132- // Saves files bigger than 64KB standalone instead of embedding them.
132+ // / Saves files bigger than 64KB standalone instead of embedding them.
133133 MaxEmbeddedSize = 64LL * 1024LL - 1 ,
134134 };
135135
@@ -138,6 +138,7 @@ class TrieRecord {
138138 FileOffset Offset;
139139 };
140140
141+ // / Pack StorageKind and Offset from Data into 8 byte TrieRecord.
141142 static uint64_t pack (Data D) {
142143 assert (D.Offset .get () < (int64_t )(1ULL << 56 ));
143144 uint64_t Packed = uint64_t (D.SK ) << 56 | D.Offset .get ();
@@ -150,6 +151,7 @@ class TrieRecord {
150151 return Packed;
151152 }
152153
154+ // Unpack TrieRecord into Data.
153155 static Data unpack (uint64_t Packed) {
154156 Data D;
155157 if (!Packed)
@@ -221,7 +223,7 @@ struct DataRecordHandle {
221223 0 ,
222224 " Not enough bits" );
223225
224- // layout of the DataRecordHandle and how to decode it.
226+ // / Layout of the DataRecordHandle and how to decode it.
225227 struct LayoutFlags {
226228 NumRefsFlags NumRefs;
227229 DataSizeFlags DataSize;
@@ -287,10 +289,12 @@ struct DataRecordHandle {
287289 return getDataRelOffset () + getDataSize () + 1 ;
288290 }
289291
292+ // / Describe the layout of data stored and how to decode from
293+ // / DataRecordHandle.
290294 struct Layout {
291295 explicit Layout (const Input &I);
292296
293- LayoutFlags Flags{} ;
297+ LayoutFlags Flags;
294298 uint64_t DataSize = 0 ;
295299 uint32_t NumRefs = 0 ;
296300 int64_t RefsRelOffset = 0 ;
@@ -349,7 +353,7 @@ struct OnDiskContent {
349353 std::optional<ArrayRef<char >> Bytes;
350354};
351355
352- // Data loaded inside the memory from standalone file.
356+ // / Data loaded inside the memory from standalone file.
353357class StandaloneDataInMemory {
354358public:
355359 OnDiskContent getContent () const ;
@@ -382,9 +386,8 @@ template <size_t NumShards> class StandaloneDataMap {
382386 static_assert (isPowerOf2_64(NumShards), " Expected power of 2" );
383387
384388public:
385- const StandaloneDataInMemory &
386- insert (ArrayRef<uint8_t > Hash, TrieRecord::StorageKind SK,
387- std::unique_ptr<sys::fs::mapped_file_region> Region);
389+ uintptr_t insert (ArrayRef<uint8_t > Hash, TrieRecord::StorageKind SK,
390+ std::unique_ptr<sys::fs::mapped_file_region> Region);
388391
389392 const StandaloneDataInMemory *lookup (ArrayRef<uint8_t > Hash) const ;
390393 bool count (ArrayRef<uint8_t > Hash) const { return bool (lookup (Hash)); }
@@ -409,27 +412,7 @@ template <size_t NumShards> class StandaloneDataMap {
409412
410413using StandaloneDataMapTy = StandaloneDataMap<16 >;
411414
412- struct InternalHandle {
413- FileOffset getAsFileOffset () const { return *DataOffset; }
414-
415- uint64_t getRawData () const {
416- if (DataOffset) {
417- uint64_t Raw = DataOffset->get ();
418- assert (!(Raw & 0x1 ));
419- return Raw;
420- }
421- uint64_t Raw = reinterpret_cast <uintptr_t >(SDIM);
422- assert (!(Raw & 0x1 ));
423- return Raw | 1 ;
424- }
425-
426- explicit InternalHandle (FileOffset DataOffset) : DataOffset(DataOffset) {}
427- explicit InternalHandle (uint64_t DataOffset) : DataOffset(DataOffset) {}
428- explicit InternalHandle (const StandaloneDataInMemory &SDIM) : SDIM(&SDIM) {}
429- std::optional<FileOffset> DataOffset;
430- const StandaloneDataInMemory *SDIM = nullptr ;
431- };
432-
415+ // / A vector of internal node references.
433416class InternalRefVector {
434417public:
435418 void push_back (InternalRef Ref) {
@@ -476,6 +459,18 @@ DataRecordHandle::create(function_ref<char *(size_t Size)> Alloc,
476459 return constructImpl (Alloc (L.getTotalSize ()), I, L);
477460}
478461
462+ ObjectHandle ObjectHandle::fromFileOffset (FileOffset Offset) {
463+ // Store the file offset as it is.
464+ assert (!(Offset.get () & 0x1 ));
465+ return ObjectHandle (Offset.get ());
466+ }
467+
468+ ObjectHandle ObjectHandle::fromMemory (uintptr_t Ptr) {
469+ // Store the pointer from memory with lowest bit set.
470+ assert (!(Ptr & 0x1 ));
471+ return ObjectHandle (Ptr | 1 );
472+ }
473+
479474// / Proxy for an on-disk index record.
480475struct OnDiskGraphDB ::IndexProxy {
481476 FileOffset Offset;
@@ -484,15 +479,15 @@ struct OnDiskGraphDB::IndexProxy {
484479};
485480
486481template <size_t N>
487- const StandaloneDataInMemory & StandaloneDataMap<N>::insert(
482+ uintptr_t StandaloneDataMap<N>::insert(
488483 ArrayRef<uint8_t > Hash, TrieRecord::StorageKind SK,
489484 std::unique_ptr<sys::fs::mapped_file_region> Region) {
490485 auto &S = getShard (Hash);
491486 std::lock_guard<std::mutex> Lock (S.Mutex );
492487 auto &V = S.Map [Hash.data ()];
493488 if (!V)
494489 V = std::make_unique<StandaloneDataInMemory>(std::move (Region), SK);
495- return *V ;
490+ return reinterpret_cast < uintptr_t >(V. get ()) ;
496491}
497492
498493template <size_t N>
@@ -1168,20 +1163,16 @@ ArrayRef<uint8_t> OnDiskGraphDB::getDigest(const IndexProxy &I) const {
11681163
11691164static OnDiskContent getContentFromHandle (const OnDiskDataAllocator &DataPool,
11701165 ObjectHandle OH) {
1171- auto getInternalHandle = [](ObjectHandle Handle) -> InternalHandle {
1172- uint64_t Data = Handle.getOpaqueData ();
1173- if (Data & 1 )
1174- return InternalHandle (*reinterpret_cast <const StandaloneDataInMemory *>(
1175- Data & (-1ULL << 1 )));
1176- return InternalHandle (Data);
1177- };
1178-
1179- InternalHandle Handle = getInternalHandle (OH);
1180- if (Handle.SDIM )
1181- return Handle.SDIM ->getContent ();
1166+ // Decode ObjectHandle to locate the stored content.
1167+ uint64_t Data = OH.getOpaqueData ();
1168+ if (Data & 1 ) {
1169+ const auto *SDIM =
1170+ reinterpret_cast <const StandaloneDataInMemory *>(Data & (-1ULL << 1 ));
1171+ return SDIM->getContent ();
1172+ }
11821173
1183- auto DataHandle = cantFail (
1184- DataRecordHandle::getFromDataPool (DataPool, Handle. getAsFileOffset ( )));
1174+ auto DataHandle =
1175+ cantFail ( DataRecordHandle::getFromDataPool (DataPool, FileOffset (Data )));
11851176 assert (DataHandle.getData ().end ()[0 ] == 0 && " Null termination" );
11861177 return OnDiskContent{DataHandle, std::nullopt };
11871178}
@@ -1215,12 +1206,8 @@ OnDiskGraphDB::load(ObjectID ExternalRef) {
12151206 return faultInFromUpstream (ExternalRef);
12161207 }
12171208
1218- auto toObjectHandle = [](InternalHandle H) -> ObjectHandle {
1219- return ObjectHandle::fromOpaqueData (H.getRawData ());
1220- };
1221-
12221209 if (Object.SK == TrieRecord::StorageKind::DataPool)
1223- return toObjectHandle ( InternalHandle ( Object.Offset ) );
1210+ return ObjectHandle::fromFileOffset ( Object.Offset );
12241211
12251212 // Only TrieRecord::StorageKind::Standalone (and variants) need to be
12261213 // explicitly loaded.
@@ -1263,9 +1250,9 @@ OnDiskGraphDB::load(ObjectID ExternalRef) {
12631250 if (EC)
12641251 return createCorruptObjectError (getDigest (*I));
12651252
1266- return toObjectHandle (
1267- InternalHandle ( static_cast <StandaloneDataMapTy *>(StandaloneData)
1268- ->insert (I->Hash , Object.SK , std::move (Region) )));
1253+ return ObjectHandle::fromMemory (
1254+ static_cast <StandaloneDataMapTy *>(StandaloneData)
1255+ ->insert (I->Hash , Object.SK , std::move (Region)));
12691256}
12701257
12711258Expected<bool > OnDiskGraphDB::isMaterialized (ObjectID Ref) {
0 commit comments