summaryrefslogtreecommitdiffstats
path: root/storage/src/vespa/storageapi/message/bucketsplitting.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/src/vespa/storageapi/message/bucketsplitting.h')
-rw-r--r--storage/src/vespa/storageapi/message/bucketsplitting.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/storage/src/vespa/storageapi/message/bucketsplitting.h b/storage/src/vespa/storageapi/message/bucketsplitting.h
new file mode 100644
index 00000000000..584cdfd5638
--- /dev/null
+++ b/storage/src/vespa/storageapi/message/bucketsplitting.h
@@ -0,0 +1,120 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include <vespa/storageapi/buckets/bucketinfo.h>
+#include <vespa/storageapi/messageapi/bucketcommand.h>
+#include <vespa/storageapi/messageapi/bucketinforeply.h>
+#include <vespa/storageapi/messageapi/maintenancecommand.h>
+
+namespace storage::api {
+
+/**
+ * @class SplitBucketCommand
+ * @ingroup message
+ *
+ * @brief Split a bucket
+ *
+ * Splits a bucket into two parts using the next split bit that is unused.
+ *
+ * Distributors can issue splits for multiple reasons:
+ * - Inconsistent buckets, so we need to split buckets containing others until
+ * they are either split equally, or no longer contains others.
+ * - Buckets that are too large are split to reduce file size.
+ * - Buckets with too many entries are split to reduce amount of metadata.
+ *
+ * In the first case, min and max split bits can be set. This will make storage
+ * able to split several bits at a time, but know where to stop.
+ *
+ * In the second case, min byte size can be set, to ensure that we don't split
+ * bucket more one step if the copy at the time of processing is
+ * actually smaller. Since removes can happen in the meantime, the min byte size
+ * should be smaller than the limit we use for splitting. Suggesting half.
+ *
+ * Similarily we can do as the second case in the third case too, just using
+ * min doc count as limiter instead.
+ *
+ * If neither are specified, min/max split bits limits nothing, but the sizes
+ * are set to max, which ensures that only one split step is taken.
+ */
+class SplitBucketCommand : public MaintenanceCommand {
+private:
+ uint8_t _minSplitBits;
+ uint8_t _maxSplitBits;
+ uint32_t _minByteSize;
+ uint32_t _minDocCount;
+
+public:
+ SplitBucketCommand(const document::Bucket& bucket);
+
+ uint8_t getMinSplitBits() const { return _minSplitBits; }
+ uint8_t getMaxSplitBits() const { return _maxSplitBits; }
+ uint32_t getMinByteSize() const { return _minByteSize; }
+ uint32_t getMinDocCount() const { return _minDocCount; }
+
+ void setMinSplitBits(uint8_t v) { _minSplitBits = v; }
+ void setMaxSplitBits(uint8_t v) { _maxSplitBits = v; }
+ void setMinByteSize(uint32_t v) { _minByteSize = v; }
+ void setMinDocCount(uint32_t v) { _minDocCount = v; }
+
+ void print(std::ostream& out, bool verbose, const std::string& indent) const override;
+
+ DECLARE_STORAGECOMMAND(SplitBucketCommand, onSplitBucket)
+};
+
+/**
+ * @class SplitBucketReply
+ * @ingroup message
+ *
+ * @brief Reply of a split bucket command.
+ */
+class SplitBucketReply : public BucketReply {
+public:
+ typedef std::pair<document::BucketId, BucketInfo> Entry;
+ explicit SplitBucketReply(const SplitBucketCommand& cmd);
+ std::vector<Entry>& getSplitInfo() { return _result; }
+ const std::vector<Entry>& getSplitInfo() const { return _result; }
+
+ void print(std::ostream& out, bool verbose, const std::string& indent) const override;
+ DECLARE_STORAGEREPLY(SplitBucketReply, onSplitBucketReply)
+private:
+ std::vector<Entry> _result;
+};
+
+/**
+ * @class JoinBucketCommand
+ * @ingroup message
+ *
+ * @brief Join two buckets
+ *
+ * Joins two buckets on the same node into a bucket with one fewer split bit.
+ */
+class JoinBucketsCommand : public MaintenanceCommand {
+ std::vector<document::BucketId> _sources;
+ uint8_t _minJoinBits;
+public:
+ explicit JoinBucketsCommand(const document::Bucket &target);
+ std::vector<document::BucketId>& getSourceBuckets() { return _sources; }
+ const std::vector<document::BucketId>& getSourceBuckets() const { return _sources; }
+ void setMinJoinBits(uint8_t minJoinBits) { _minJoinBits = minJoinBits; }
+ uint8_t getMinJoinBits() const { return _minJoinBits; }
+ void print(std::ostream& out, bool verbose, const std::string& indent) const override;
+ DECLARE_STORAGECOMMAND(JoinBucketsCommand, onJoinBuckets)
+};
+
+/**
+ * @class JoinBucketsReply
+ * @ingroup message
+ *
+ * @brief Reply of a join bucket command.
+ */
+class JoinBucketsReply : public BucketInfoReply {
+ std::vector<document::BucketId> _sources;
+public:
+ explicit JoinBucketsReply(const JoinBucketsCommand& cmd);
+ JoinBucketsReply(const JoinBucketsCommand& cmd, const BucketInfo& bucketInfo);
+ const std::vector<document::BucketId>& getSourceBuckets() const { return _sources; }
+ void print(std::ostream& out, bool verbose, const std::string& indent) const override;
+ DECLARE_STORAGEREPLY(JoinBucketsReply, onJoinBucketsReply)
+};
+
+}