implement SetProperties in PropertyStore
This commit is contained in:
@@ -869,6 +869,26 @@ SpecificPropertyAndBufferInfo FindSpecificPropertyAndBufferInfo(Reader *reader,
|
||||
return {property_begin, property_end, property_end - property_begin, all_begin, all_end, all_end - all_begin};
|
||||
}
|
||||
|
||||
// Function used to move to the position where the property should be in the data
|
||||
// buffer.
|
||||
// The `property_size` will be `0`
|
||||
// and `property_begin` will be equal to `property_end`. Positions and size of
|
||||
// all properties is always calculated (even if the specific property isn't
|
||||
// found).
|
||||
//
|
||||
// @sa FindSpecificProperty
|
||||
SpecificPropertyAndBufferInfo SkipReaderAndGetBufferInfo(Reader *reader, uint64_t size) {
|
||||
uint64_t property_begin = reader->GetPosition();
|
||||
uint64_t property_end = reader->GetPosition();
|
||||
uint64_t all_begin = reader->GetPosition();
|
||||
uint64_t all_end = reader->GetPosition();
|
||||
reader->SkipBytes(size);
|
||||
property_begin = reader->GetPosition();
|
||||
property_end = reader->GetPosition();
|
||||
all_end = reader->GetPosition();
|
||||
return {property_begin, property_end, property_end - property_begin, all_begin, all_end, all_end - all_begin};
|
||||
}
|
||||
|
||||
// All data buffers will be allocated to a power of 8 size.
|
||||
uint64_t ToPowerOf8(uint64_t size) {
|
||||
uint64_t mod = size % 8;
|
||||
@@ -1146,6 +1166,57 @@ bool PropertyStore::SetProperty(PropertyId property, const PropertyValue &value)
|
||||
return !existed;
|
||||
}
|
||||
|
||||
// use this function only when inserting new properties
|
||||
bool PropertyStore::SetProperties(std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||
uint64_t size;
|
||||
uint8_t *data;
|
||||
std::tie(size, data) = GetSizeData(buffer_);
|
||||
MG_ASSERT(size == 0, "Invalid database state!");
|
||||
|
||||
uint64_t property_size = 0;
|
||||
{
|
||||
Writer writer;
|
||||
for (const auto &[property, value] : properties) {
|
||||
EncodeProperty(&writer, property, value);
|
||||
property_size = writer.Written();
|
||||
}
|
||||
}
|
||||
|
||||
auto property_size_to_power_of_8 = ToPowerOf8(property_size);
|
||||
if (property_size <= sizeof(buffer_) - 1) {
|
||||
// Use the local buffer.
|
||||
buffer_[0] = kUseLocalBuffer;
|
||||
size = sizeof(buffer_) - 1;
|
||||
data = &buffer_[1];
|
||||
} else {
|
||||
// Allocate a new external buffer.
|
||||
auto alloc_data = new uint8_t[property_size_to_power_of_8];
|
||||
auto alloc_size = property_size_to_power_of_8;
|
||||
|
||||
SetSizeData(buffer_, alloc_size, alloc_data);
|
||||
|
||||
size = alloc_size;
|
||||
data = alloc_data;
|
||||
}
|
||||
|
||||
// Encode the property into the data buffer.
|
||||
Writer writer(data, size);
|
||||
|
||||
for (const auto &[property, value] : properties) {
|
||||
MG_ASSERT(EncodeProperty(&writer, property, value), "Invalid database state!");
|
||||
property_size = writer.Written();
|
||||
}
|
||||
|
||||
auto metadata = writer.WriteMetadata();
|
||||
if (metadata) {
|
||||
// If there is any space left in the buffer we add a tombstone to
|
||||
// indicate that there are no more properties to be decoded.
|
||||
metadata->Set({Type::EMPTY});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyStore::ClearProperties() {
|
||||
bool in_local_buffer = false;
|
||||
uint64_t size;
|
||||
|
||||
@@ -61,6 +61,8 @@ class PropertyStore {
|
||||
/// @throw std::bad_alloc
|
||||
bool SetProperty(PropertyId property, const PropertyValue &value);
|
||||
|
||||
bool SetProperties(std::map<storage::PropertyId, storage::PropertyValue> &properties);
|
||||
|
||||
/// Remove all properties and return `true` if any removal took place.
|
||||
/// `false` is returned if there were no properties to remove. The time
|
||||
/// complexity of this function is O(1).
|
||||
|
||||
@@ -258,10 +258,12 @@ Result<std::vector<storage::PropertyValue>> VertexAccessor::SetBatchProperties(
|
||||
if (vertex_->deleted) return Error::DELETED_OBJECT;
|
||||
|
||||
std::vector<storage::PropertyValue> new_values;
|
||||
|
||||
vertex_->properties.SetProperties(properties);
|
||||
|
||||
for (const auto &[property, value] : properties) {
|
||||
auto current_value = vertex_->properties.GetEmptyProperty();
|
||||
CreateAndLinkDelta(transaction_, vertex_, Delta::SetPropertyTag(), property, current_value);
|
||||
vertex_->properties.SetProperty(property, value);
|
||||
UpdateOnSetProperty(indices_, property, value, vertex_, *transaction_);
|
||||
new_values.emplace_back(current_value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user