mirror of
https://github.com/facebook/sapling.git
synced 2024-10-05 14:28:17 +03:00
39411c9714
Summary: Test out `match` by porting JournalDelta to it from `std::visit`. Much nicer! Reviewed By: mshroyer Differential Revision: D45629545 fbshipit-source-id: 96af83589cdfed26adf4d67f4a97dc2b375caa28
157 lines
4.7 KiB
C++
157 lines
4.7 KiB
C++
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#include "eden/fs/journal/JournalDelta.h"
|
|
#include <folly/logging/xlog.h>
|
|
#include "eden/fs/utils/Match.h"
|
|
|
|
namespace facebook::eden {
|
|
|
|
FileChangeJournalDelta::FileChangeJournalDelta(
|
|
RelativePathPiece fileName,
|
|
FileChangeJournalDelta::Created)
|
|
: path1{fileName.copy()},
|
|
info1{PathChangeInfo{false, true}},
|
|
isPath1Valid{true} {}
|
|
|
|
FileChangeJournalDelta::FileChangeJournalDelta(
|
|
RelativePathPiece fileName,
|
|
FileChangeJournalDelta::Removed)
|
|
: path1{fileName.copy()},
|
|
info1{PathChangeInfo{true, false}},
|
|
isPath1Valid{true} {}
|
|
|
|
FileChangeJournalDelta::FileChangeJournalDelta(
|
|
RelativePathPiece fileName,
|
|
FileChangeJournalDelta::Changed)
|
|
: path1{fileName.copy()},
|
|
info1{PathChangeInfo{true, true}},
|
|
isPath1Valid{true} {}
|
|
|
|
FileChangeJournalDelta::FileChangeJournalDelta(
|
|
RelativePathPiece oldName,
|
|
RelativePathPiece newName,
|
|
FileChangeJournalDelta::Renamed)
|
|
: path1{oldName.copy()},
|
|
path2{newName.copy()},
|
|
info1{PathChangeInfo{true, false}},
|
|
info2{PathChangeInfo{false, true}},
|
|
isPath1Valid{true},
|
|
isPath2Valid{true} {}
|
|
|
|
FileChangeJournalDelta::FileChangeJournalDelta(
|
|
RelativePathPiece oldName,
|
|
RelativePathPiece newName,
|
|
FileChangeJournalDelta::Replaced)
|
|
: path1{oldName.copy()},
|
|
path2{newName.copy()},
|
|
info1{PathChangeInfo{true, false}},
|
|
info2{PathChangeInfo{true, true}},
|
|
isPath1Valid{true},
|
|
isPath2Valid{true} {}
|
|
|
|
size_t FileChangeJournalDelta::estimateMemoryUsage() const {
|
|
size_t mem = sizeof(FileChangeJournalDelta);
|
|
|
|
/* NOTE: The following code assumes an unordered_set is separated into an
|
|
* array of buckets, each one being a chain of nodes containing a next
|
|
* pointer, a key-value pair, and a stored hash
|
|
*/
|
|
if (isPath1Valid) {
|
|
mem += facebook::eden::estimateIndirectMemoryUsage(path1);
|
|
}
|
|
if (isPath2Valid) {
|
|
mem += facebook::eden::estimateIndirectMemoryUsage(path2);
|
|
}
|
|
|
|
return mem;
|
|
}
|
|
|
|
size_t RootUpdateJournalDelta::estimateMemoryUsage() const {
|
|
size_t mem = sizeof(RootUpdateJournalDelta);
|
|
|
|
/* NOTE: The following code assumes an unordered_set is separated into an
|
|
* array of buckets, each one being a chain of nodes containing a next
|
|
* pointer, a key-value pair, and a stored hash
|
|
*/
|
|
|
|
// Calculate Memory For Nodes in Each Bucket (Pointer to element and next)
|
|
size_t set_elem_size = folly::goodMallocSize(
|
|
sizeof(void*) + sizeof(decltype(uncleanPaths)::value_type) +
|
|
sizeof(size_t));
|
|
for (unsigned long i = 0; i < uncleanPaths.bucket_count(); ++i) {
|
|
mem += set_elem_size * uncleanPaths.bucket_size(i);
|
|
}
|
|
|
|
// Calculate Memory Usage of Bucket List
|
|
mem += folly::goodMallocSize(sizeof(void*) * uncleanPaths.bucket_count());
|
|
|
|
// Calculate Memory Usage used indirectly by elements
|
|
for (auto& path : uncleanPaths) {
|
|
mem += facebook::eden::estimateIndirectMemoryUsage(path);
|
|
}
|
|
|
|
return mem;
|
|
}
|
|
|
|
std::unordered_map<RelativePath, PathChangeInfo>
|
|
FileChangeJournalDelta::getChangedFilesInOverlay() const {
|
|
std::unordered_map<RelativePath, PathChangeInfo> changedFilesInOverlay;
|
|
if (isPath1Valid) {
|
|
changedFilesInOverlay[path1] = info1;
|
|
}
|
|
if (isPath2Valid) {
|
|
changedFilesInOverlay[path2] = info2;
|
|
}
|
|
return changedFilesInOverlay;
|
|
}
|
|
|
|
bool FileChangeJournalDelta::isModification() const {
|
|
return isPath1Valid && !isPath2Valid && info1.existedBefore &&
|
|
info1.existedAfter;
|
|
}
|
|
|
|
bool FileChangeJournalDelta::isSameAction(
|
|
const FileChangeJournalDelta& other) const {
|
|
return isPath1Valid == other.isPath1Valid && info1 == other.info1 &&
|
|
path1 == other.path1 && isPath2Valid == other.isPath2Valid &&
|
|
info2 == other.info2 && path2 == other.path2;
|
|
}
|
|
|
|
JournalDeltaPtr::JournalDeltaPtr(std::nullptr_t) {}
|
|
|
|
JournalDeltaPtr::JournalDeltaPtr(FileChangeJournalDelta* p) : data_{p} {
|
|
XCHECK(p);
|
|
}
|
|
|
|
JournalDeltaPtr::JournalDeltaPtr(RootUpdateJournalDelta* p) : data_{p} {
|
|
XCHECK(p);
|
|
}
|
|
|
|
size_t JournalDeltaPtr::estimateMemoryUsage() const {
|
|
return match(
|
|
data_,
|
|
[](std::monostate) -> size_t { return 0; },
|
|
[](auto* delta) { return delta->estimateMemoryUsage(); });
|
|
}
|
|
|
|
const JournalDelta* JournalDeltaPtr::operator->() const noexcept {
|
|
return match(
|
|
data_,
|
|
[](std::monostate) -> JournalDelta* { return nullptr; },
|
|
[](auto* delta) -> JournalDelta* { return delta; });
|
|
}
|
|
|
|
FileChangeJournalDelta* JournalDeltaPtr::getAsFileChangeJournalDelta() {
|
|
return match(
|
|
data_,
|
|
[](FileChangeJournalDelta* p) { return p; },
|
|
[](auto) -> FileChangeJournalDelta* { return nullptr; });
|
|
}
|
|
|
|
} // namespace facebook::eden
|