|
63 | 63 | #include "llvm/Support/MemoryBuffer.h"
|
64 | 64 | #include "llvm/Support/Path.h"
|
65 | 65 | #include "llvm/Support/Process.h"
|
66 |
| -#include "llvm/Support/xxhash.h" |
67 | 66 | #include <optional>
|
68 | 67 |
|
69 | 68 | #if __has_include(<sys/mount.h>)
|
@@ -618,7 +617,6 @@ Error OnDiskGraphDB::TempFile::keep(const Twine &Name) {
|
618 | 617 | sys::fs::file_t File = sys::fs::convertFDToNativeFile(FD);
|
619 | 618 | if (std::error_code EC = sys::fs::closeFile(File))
|
620 | 619 | return errorCodeToError(EC);
|
621 |
| - |
622 | 620 | FD = -1;
|
623 | 621 |
|
624 | 622 | return errorCodeToError(RenameEC);
|
@@ -1270,24 +1268,49 @@ void OnDiskGraphDB::getStandalonePath(StringRef Suffix, const IndexProxy &I,
|
1270 | 1268 | PersistentPath.assign(RootPath.begin(), RootPath.end());
|
1271 | 1269 | if (TempPath)
|
1272 | 1270 | TempPath->assign(RootPath.begin(), RootPath.end());
|
1273 |
| - SmallVector<char, 256> FileNameBuffer; |
1274 |
| - StringRef FileName = |
1275 |
| - (FilePrefix + Twine(I.Offset.get()) + Suffix).toStringRef(FileNameBuffer); |
1276 |
| - |
1277 |
| - uint64_t FileNameHash = xxHash64(FileName); |
1278 |
| - |
1279 |
| - // This is around 10 bits of entropy given we're using radix-36 |
1280 |
| - static const unsigned IntermediateDirNameLength = 2; |
1281 |
| - static const char Radix36Chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
1282 |
| - static_assert(sizeof(Radix36Chars) == 36 + /* null */ 1); |
1283 |
| - SmallString<IntermediateDirNameLength> IntermediateDirName; |
1284 |
| - for (unsigned Ch = 0; Ch < IntermediateDirNameLength; ++Ch) { |
1285 |
| - IntermediateDirName.push_back(Radix36Chars[FileNameHash % 36]); |
1286 |
| - FileNameHash /= 36; |
| 1271 | + |
| 1272 | + static const unsigned IntermediateDirCount = 2; |
| 1273 | + static const unsigned EntropyPerIntermediateDir = 8; |
| 1274 | + static const unsigned CharactersPerDirName = |
| 1275 | + ((EntropyPerIntermediateDir + 15) & ~7) / 8; |
| 1276 | + |
| 1277 | + static const unsigned TotalEntropyBits = |
| 1278 | + IntermediateDirCount * EntropyPerIntermediateDir; |
| 1279 | + static const unsigned HashByteCount = ((TotalEntropyBits + 7) & ~7) / 8; |
| 1280 | + static_assert(HashByteCount <= sizeof(uint32_t)); |
| 1281 | + |
| 1282 | + // We will never need 32 bits of entropy, so we just assert that now as it |
| 1283 | + // means we don't need to worry about overflows in the shifts below. |
| 1284 | + static_assert(TotalEntropyBits < 32); |
| 1285 | + |
| 1286 | + // It would be nice if there was a way to statically assert the size of an |
| 1287 | + // ArrayRef. |
| 1288 | + assert(I.Hash.size() >= sizeof(uint32_t)); |
| 1289 | + |
| 1290 | + uint32_t Hash; |
| 1291 | + memcpy(&Hash, I.Hash.data(), sizeof(Hash)); |
| 1292 | + |
| 1293 | + for (unsigned IntermediateDir = 0; IntermediateDir < IntermediateDirCount; ++IntermediateDir) { |
| 1294 | + unsigned DirValue = Hash & ((1u << EntropyPerIntermediateDir) - 1); |
| 1295 | + Hash >>= EntropyPerIntermediateDir; |
| 1296 | + char DirNameCharacters[CharactersPerDirName]; |
| 1297 | + for (unsigned CharIdx = 0; CharIdx < CharactersPerDirName; ++CharIdx) { |
| 1298 | + // Mod and divide for clarity, this gets lowered to bit operations as |
| 1299 | + // expected. |
| 1300 | + unsigned CharValue = DirValue % 16; |
| 1301 | + DirValue /= 16; |
| 1302 | + DirNameCharacters[CharIdx] = |
| 1303 | + hexdigit(CharValue, /*LowerCase=*/false); |
| 1304 | + } |
| 1305 | + sys::path::append(PersistentPath, StringRef(DirNameCharacters, CharactersPerDirName)); |
1287 | 1306 | }
|
1288 |
| - sys::path::append(PersistentPath, IntermediateDirName, FileName); |
1289 |
| - if (TempPath) |
1290 |
| - sys::path::append(*TempPath, FileName); |
| 1307 | + auto AppendFileName = [&](Twine FileName) { |
| 1308 | + sys::path::append(PersistentPath, FileName); |
| 1309 | + |
| 1310 | + if (TempPath) |
| 1311 | + sys::path::append(*TempPath, FileName); |
| 1312 | + }; |
| 1313 | + AppendFileName(FilePrefix + Twine(I.Offset.get()) + Suffix); |
1291 | 1314 | }
|
1292 | 1315 |
|
1293 | 1316 | OnDiskContent OnDiskGraphDB::getContentFromHandle(ObjectHandle OH) const {
|
|
0 commit comments