diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2013-06-19 21:03:50 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2013-06-19 21:03:50 +0000 |
commit | 9fbe530d740ced34c664fddc4b9aec92234fcf27 (patch) | |
tree | 3d696f5c582c88c90cab6a6223444e36667d267d /llvm/lib/Support | |
parent | d95d4478852c415460292ce45831028a9aa2e817 (diff) | |
download | bcm5719-llvm-9fbe530d740ced34c664fddc4b9aec92234fcf27.tar.gz bcm5719-llvm-9fbe530d740ced34c664fddc4b9aec92234fcf27.zip |
Modified the implementation of fs::GetUniqueID on Windows such that it actually finds a unique identifier for a file. Also adds unit tests for GetUniqueID.
llvm-svn: 184351
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r-- | llvm/lib/Support/Windows/PathV2.inc | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/llvm/lib/Support/Windows/PathV2.inc b/llvm/lib/Support/Windows/PathV2.inc index bec95e36cc5..e6888f93e68 100644 --- a/llvm/lib/Support/Windows/PathV2.inc +++ b/llvm/lib/Support/Windows/PathV2.inc @@ -426,15 +426,20 @@ error_code file_size(const Twine &path, uint64_t &result) { } error_code GetUniqueID(const Twine Path, uint64_t &Result) { - // FIXME: this is only unique if the file is accessed by the same file path. - // How do we do this for C:\dir\file and ..\dir\file ? Unix has inode - // numbers, but the concept doesn't exist in Windows. - SmallString<128> Storage; - StringRef P = Path.toStringRef(Storage); - uint64_t UniqueID = 0; - for (StringRef::iterator I = P.begin(), E = P.end(); I != E; ++I) - UniqueID += *I; - Result = UniqueID; + file_status Status; + if (error_code E = status(Path, Status)) + return E; + + // The file is uniquely identified by the volume serial number along + // with the 64-bit file identifier. + Result = (static_cast<uint64_t>(Status.FileIndexHigh) << 32ULL) | + static_cast<uint64_t>(Status.FileIndexLow); + + // Because the serial number is 32-bits, but we've already used up all 64 + // bits for the file index, XOR the serial number into the high 32 bits of + // the resulting value. We could potentially get collisons from this, but + // the likelihood is low. + Result ^= (static_cast<uint64_t>(Status.VolumeSerialNumber) << 32ULL); return error_code::success(); } |