sapling/eden/fs/store/SerializedBlobMetadata.cpp
Katie Mancini 550400364d introduce tree metadata storage in local store
Summary:
This introduces a class to manipulate the metadata for all the entries in a
tree. This adds serialization and deserialization to this class so that it can
be written to the local store.

Why do we need this? We need some way to easily check when we have already
fetched metadata for a tree and do not need to refetch this from the server to
avoid expensive network requests. Later diffs add functionally to store the metadata
for tree entries in the local store under the tree hash using this class.

Reviewed By: chadaustin

Differential Revision: D21959015

fbshipit-source-id: 0c0e8750737f3076c1f9604d0319cab7f2658656
2020-07-10 16:03:32 -07:00

69 lines
1.7 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 "SerializedBlobMetadata.h"
#include <folly/Format.h>
#include <folly/Range.h>
#include <folly/lang/Bits.h>
#include <eden/fs/model/Hash.h>
#include <eden/fs/store/BlobMetadata.h>
namespace facebook {
namespace eden {
SerializedBlobMetadata::SerializedBlobMetadata(const BlobMetadata& metadata) {
serialize(metadata.sha1, metadata.size);
}
SerializedBlobMetadata::SerializedBlobMetadata(
const Hash& contentsHash,
uint64_t blobSize) {
serialize(contentsHash, blobSize);
}
folly::ByteRange SerializedBlobMetadata::slice() const {
return folly::ByteRange{data_};
}
BlobMetadata SerializedBlobMetadata::parse(
Hash blobID,
const StoreResult& result) {
auto bytes = result.bytes();
if (bytes.size() != SIZE) {
throw std::invalid_argument(folly::sformat(
"Blob metadata for {} had unexpected size {}. Could not deserialize.",
blobID.toString(),
bytes.size()));
}
return unslice(bytes);
}
BlobMetadata SerializedBlobMetadata::unslice(folly::ByteRange bytes) {
uint64_t blobSizeBE;
memcpy(&blobSizeBE, bytes.data(), sizeof(uint64_t));
bytes.advance(sizeof(uint64_t));
auto contentsHash = Hash{bytes};
return BlobMetadata{contentsHash, folly::Endian::big(blobSizeBE)};
}
void SerializedBlobMetadata::serialize(
const Hash& contentsHash,
uint64_t blobSize) {
uint64_t blobSizeBE = folly::Endian::big(blobSize);
memcpy(data_.data(), &blobSizeBE, sizeof(uint64_t));
memcpy(
data_.data() + sizeof(uint64_t),
contentsHash.getBytes().data(),
Hash::RAW_SIZE);
}
} // namespace eden
} // namespace facebook