2016-05-12 23:43:17 +03:00
|
|
|
/*
|
2019-06-20 02:58:25 +03:00
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
2016-05-12 23:43:17 +03:00
|
|
|
*
|
2019-06-20 02:58:25 +03:00
|
|
|
* This software may be used and distributed according to the terms of the
|
|
|
|
* GNU General Public License version 2.
|
2016-05-12 23:43:17 +03:00
|
|
|
*/
|
2019-10-11 15:26:59 +03:00
|
|
|
|
2016-05-12 23:43:17 +03:00
|
|
|
#pragma once
|
|
|
|
|
2016-07-06 03:41:43 +03:00
|
|
|
#include <algorithm>
|
2016-05-12 23:43:17 +03:00
|
|
|
#include <vector>
|
|
|
|
#include "Hash.h"
|
|
|
|
#include "TreeEntry.h"
|
|
|
|
|
|
|
|
namespace facebook {
|
|
|
|
namespace eden {
|
|
|
|
|
|
|
|
class Tree {
|
|
|
|
public:
|
2016-07-25 22:33:39 +03:00
|
|
|
explicit Tree(std::vector<TreeEntry>&& entries, const Hash& hash = Hash())
|
2016-05-12 23:43:17 +03:00
|
|
|
: hash_(hash), entries_(std::move(entries)) {}
|
|
|
|
|
|
|
|
const Hash& getHash() const {
|
|
|
|
return hash_;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<TreeEntry>& getTreeEntries() const {
|
|
|
|
return entries_;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TreeEntry& getEntryAt(size_t index) const {
|
|
|
|
return entries_.at(index);
|
|
|
|
}
|
|
|
|
|
2016-07-06 03:41:43 +03:00
|
|
|
const TreeEntry* getEntryPtr(PathComponentPiece path) const {
|
|
|
|
auto iter = std::lower_bound(
|
|
|
|
entries_.cbegin(),
|
|
|
|
entries_.cend(),
|
|
|
|
path,
|
|
|
|
[](const TreeEntry& entry, PathComponentPiece piece) {
|
|
|
|
return entry.getName() < piece;
|
|
|
|
});
|
|
|
|
if (UNLIKELY(iter == entries_.cend() || iter->getName() != path)) {
|
2019-05-17 21:45:24 +03:00
|
|
|
#ifdef _WIN32
|
|
|
|
// On Windows we need to do a case insensitive lookup for the file and
|
|
|
|
// directory names. For performance, we will do a case sensitive search
|
|
|
|
// first which should cover most of the cases and if not found then do a
|
|
|
|
// case sensitive search.
|
|
|
|
const auto& fileName = path.stringPiece();
|
|
|
|
for (const auto& entry : entries_) {
|
|
|
|
if (entry.getName().stringPiece().equals(
|
|
|
|
fileName, folly::AsciiCaseInsensitive())) {
|
|
|
|
return &entry;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2016-07-06 03:41:43 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return &*iter;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TreeEntry& getEntryAt(PathComponentPiece path) const {
|
|
|
|
auto entry = getEntryPtr(path);
|
|
|
|
if (!entry) {
|
|
|
|
throw std::out_of_range(
|
|
|
|
folly::to<std::string>(path, " is not present in this Tree"));
|
|
|
|
}
|
|
|
|
return *entry;
|
|
|
|
}
|
|
|
|
|
2018-06-07 00:32:41 +03:00
|
|
|
std::vector<PathComponent> getEntryNames() const {
|
|
|
|
std::vector<PathComponent> results;
|
|
|
|
results.reserve(entries_.size());
|
|
|
|
for (const auto& entry : entries_) {
|
|
|
|
results.emplace_back(entry.getName());
|
|
|
|
}
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
2016-05-12 23:43:17 +03:00
|
|
|
private:
|
|
|
|
const Hash hash_;
|
|
|
|
const std::vector<TreeEntry> entries_;
|
|
|
|
};
|
2017-07-05 21:17:03 +03:00
|
|
|
|
|
|
|
bool operator==(const Tree& tree1, const Tree& tree2);
|
|
|
|
bool operator!=(const Tree& tree1, const Tree& tree2);
|
2017-11-04 01:58:04 +03:00
|
|
|
} // namespace eden
|
|
|
|
} // namespace facebook
|