sapling/eden/fs/model/ObjectId.cpp
Andrey Chursin c24bb6096b Make ObjectId a variable length hash [proxy hash removal 4/n]
Summary:
This diff modifies ObjectId structure to support storing more information directly in ObjectId, avoiding proxy objects like HgProxyHash and ReCasDigestProxyHash.

Storing this information directly in ObjectId allows to avoid additional db access for loading/storing those proxy hash objects, reducing file access latency in hot case.

**New ObjectId format**

ObjectId can now content variable length hash.

The variable length can be used in following cases:
(1) To replace ReCasDigestProxyHash, extra 8 bytes can be used to store size portion of `remote_execution::TDigest`
(2) To replace HgProxyHash, extra 1 byte can be used to identify whether ObjectId represents ProxyHashId or an HgId.

In the future, ObjectId can contain path or other information needed to implement ACL

**Compatibility notes**

For compatibility reasons, we only currently initialize ObjectId with 20-bytes content.

This is essential to allow smooth migration to a new format
(a) Until new hash format is actually used(e.g. we switch HgBackingStore to store HgId inside ObjectId), this code is backwards compatible with other EdenFs versions. This revision can be safely rolled back and previous version of EdenFs can still read inode data written by this version
(b) When we introduce support for new ObjectId into HgBackingStore, we can gate it's usage behind config, allowing controlled slow roll out of new ObjectId format.

**ToDo**

Just to track progress of removing proxy hashes, few things are still left:
* We need different format for SerializedTreeMetadata
* We need to support new format for thriftHash
* We need to actually switch HgBackingStore to embed HgId information into ObjectId, instead of using ProxyHash

Not planned:
* Migration of ReCasDigestProxyHash - I don't know how to test it, so someone else should probably do that

Reviewed By: chadaustin

Differential Revision: D31668130

fbshipit-source-id: 720127354c648651bb35e850beb8dd252a5566b2
2021-10-22 17:52:01 -07:00

75 lines
1.8 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#include "eden/fs/model/ObjectId.h"
#include "eden/fs/model/Hash.h"
#include <folly/Conv.h>
#include <folly/Format.h>
#include <folly/String.h>
#include <folly/io/Cursor.h>
#include <folly/io/IOBuf.h>
#include <folly/ssl/OpenSSLHash.h>
#include <string>
using folly::ByteRange;
using folly::range;
using folly::ssl::OpenSSLHash;
namespace facebook::eden {
std::string ObjectId::asHexString() const {
auto bytes = getBytes();
std::string result;
folly::hexlify(bytes, result);
return result;
}
std::string ObjectId::asString() const {
auto bytes = getBytes();
return std::string(reinterpret_cast<const char*>(bytes.data()), bytes.size());
}
size_t ObjectId::getHashCode() const noexcept {
return std::hash<folly::fbstring>{}(bytes_);
}
bool ObjectId::operator==(const ObjectId& otherHash) const {
return bytes_ == otherHash.bytes_;
}
bool ObjectId::operator<(const ObjectId& otherHash) const {
return bytes_ < otherHash.bytes_;
}
ObjectId ObjectId::sha1(const folly::IOBuf& buf) {
Hash20::Storage hashBytes;
OpenSSLHash::sha1(range(hashBytes), buf);
return ObjectId{hashBytes};
}
ObjectId ObjectId::sha1(ByteRange data) {
Hash20::Storage hashBytes;
OpenSSLHash::sha1(range(hashBytes), data);
return ObjectId{hashBytes};
}
void ObjectId::throwInvalidArgument(const char* message, size_t number) {
throw std::invalid_argument(folly::to<std::string>(message, number));
}
std::ostream& operator<<(std::ostream& os, const ObjectId& hash) {
os << hash.toLogString();
return os;
}
void toAppend(const ObjectId& hash, std::string* result) {
folly::toAppend(hash.toLogString(), result);
}
} // namespace facebook::eden