blob: f07cf7b38411d393a17ee3c6bda4cf8d64f576f3 [file] [log] [blame]
Kun Yi68c81142018-12-18 11:17:14 -08001#pragma once
2
Kun Yi2765b642019-01-16 11:11:24 -08003#include "sys_file.hpp"
4
Kun Yi64dc05c2018-12-19 13:19:03 -08005#include <unistd.h>
6
Kun Yi68c81142018-12-18 11:17:14 -08007#include <cstdint>
Kun Yi64dc05c2018-12-19 13:19:03 -08008#include <memory>
Kun Yi68c81142018-12-18 11:17:14 -08009#include <string>
10#include <vector>
11
Kun Yi0a940b92019-01-07 16:33:11 -080012#include "binaryblob.pb.h"
13
Kun Yi68c81142018-12-18 11:17:14 -080014using std::size_t;
15using std::uint16_t;
16using std::uint32_t;
17using std::uint64_t;
18using std::uint8_t;
19
20namespace binstore
21{
22
23/**
24 * @class BinaryStoreInterface is an abstraction for a storage location.
Kun Yi64dc05c2018-12-19 13:19:03 -080025 * Each instance would be uniquely identified by a baseId string.
Kun Yi68c81142018-12-18 11:17:14 -080026 */
27class BinaryStoreInterface
28{
29 public:
30 virtual ~BinaryStoreInterface() = default;
31
Kun Yi64dc05c2018-12-19 13:19:03 -080032 /**
33 * @returns baseId string of the storage.
34 */
Kun Yi68c81142018-12-18 11:17:14 -080035 virtual std::string getBaseBlobId() const = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080036
37 /**
38 * @returns List of all open blob IDs, plus the base.
39 */
Kun Yi68c81142018-12-18 11:17:14 -080040 virtual std::vector<std::string> getBlobIds() const = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080041
42 /**
43 * Opens a blob given its name. If there is no one, create one.
44 * @param blobId: The blob id to operate on.
45 * @param flags: Either read flag or r/w flag has to be specified.
46 * @returns True if open/create successfully.
47 */
Kun Yi38146a02018-12-18 21:54:26 -080048 virtual bool openOrCreateBlob(const std::string& blobId,
49 uint16_t flags) = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080050
51 /**
52 * Deletes a blob given its name. If there is no one,
53 * @param blobId: The blob id to operate on.
54 * @returns True if deleted.
55 */
Kun Yic0adbc32018-12-18 22:35:29 -080056 virtual bool deleteBlob(const std::string& blobId) = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080057
58 /**
59 * Reads data from the currently opened blob.
60 * @param offset: offset into the blob to read
61 * @param requestedSize: how many bytes to read
62 * @returns Bytes able to read. Returns empty if nothing can be read or
63 * if there is no open blob.
64 */
Kun Yi68c81142018-12-18 11:17:14 -080065 virtual std::vector<uint8_t> read(uint32_t offset,
66 uint32_t requestedSize) = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080067
68 /**
69 * Writes data to the currently openend blob.
70 * @param offset: offset into the blob to write
71 * @param data: bytes to write
72 * @returns True if able to write the entire data successfully
73 */
Kun Yi68c81142018-12-18 11:17:14 -080074 virtual bool write(uint32_t offset, const std::vector<uint8_t>& data) = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080075
76 /**
Kun Yid297c9f2019-01-09 13:52:30 -080077 * Commits data to the persistent storage specified during blob init.
78 * @returns True if able to write data to sysfile successfully
Kun Yi64dc05c2018-12-19 13:19:03 -080079 */
Kun Yi68c81142018-12-18 11:17:14 -080080 virtual bool commit() = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080081
82 /**
Kun Yid297c9f2019-01-09 13:52:30 -080083 * Closes blob, which prevents further modifications. Uncommitted data will
84 * be lost.
85 * @returns True if able to close the blob successfully
Kun Yi64dc05c2018-12-19 13:19:03 -080086 */
Kun Yi68c81142018-12-18 11:17:14 -080087 virtual bool close() = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080088
89 /**
90 * TODO
91 */
Kun Yi68c81142018-12-18 11:17:14 -080092 virtual bool stat() = 0;
93};
94
Kun Yi64dc05c2018-12-19 13:19:03 -080095/**
96 * @class BinaryStore instantiates a concrete implementation of
97 * BinaryStoreInterface. The dependency on file is injected through its
98 * constructor.
99 */
100class BinaryStore : public BinaryStoreInterface
101{
102 public:
Kun Yi2765b642019-01-16 11:11:24 -0800103 BinaryStore() = delete;
104 BinaryStore(const std::string& baseBlobId, std::unique_ptr<SysFile> file,
Kun Yi64dc05c2018-12-19 13:19:03 -0800105 uint32_t maxSize) :
106 baseBlobId_(baseBlobId),
Kun Yi2765b642019-01-16 11:11:24 -0800107 file_(std::move(file)), maxSize_(maxSize)
Kun Yi64dc05c2018-12-19 13:19:03 -0800108 {
Kun Yi97be3af2019-03-05 22:43:41 -0800109 blob_.set_blob_base_id(baseBlobId_);
Kun Yi64dc05c2018-12-19 13:19:03 -0800110 }
111
Kun Yi64dc05c2018-12-19 13:19:03 -0800112 ~BinaryStore() = default;
Kun Yi2765b642019-01-16 11:11:24 -0800113
Kun Yi64dc05c2018-12-19 13:19:03 -0800114 BinaryStore(const BinaryStore&) = delete;
115 BinaryStore& operator=(const BinaryStore&) = delete;
116 BinaryStore(BinaryStore&&) = default;
117 BinaryStore& operator=(BinaryStore&&) = default;
118
119 std::string getBaseBlobId() const override;
120 std::vector<std::string> getBlobIds() const override;
121 bool openOrCreateBlob(const std::string& blobId, uint16_t flags) override;
122 bool deleteBlob(const std::string& blobId) override;
123 std::vector<uint8_t> read(uint32_t offset, uint32_t requestedSize) override;
124 bool write(uint32_t offset, const std::vector<uint8_t>& data) override;
125 bool commit() override;
126 bool close() override;
127 bool stat() override;
128
129 /**
130 * Helper factory method to create a BinaryStore instance
131 * @param baseBlobId: base id for the created instance
Kun Yi2765b642019-01-16 11:11:24 -0800132 * @param sysFile: system file object for storing binary
Kun Yi64dc05c2018-12-19 13:19:03 -0800133 * @param maxSize: max size in bytes that this BinaryStore can expand to.
134 * Writing data more than allowed size will return failure.
135 * @returns unique_ptr to constructed BinaryStore. Caller should take
136 * ownership of the instance.
137 */
138 static std::unique_ptr<BinaryStoreInterface>
139 createFromConfig(const std::string& baseBlobId,
Kun Yi2765b642019-01-16 11:11:24 -0800140 std::unique_ptr<SysFile> file, uint32_t maxSize);
Kun Yi64dc05c2018-12-19 13:19:03 -0800141
142 private:
Kun Yid297c9f2019-01-09 13:52:30 -0800143 enum class CommitState
144 {
145 Dirty, // In-memory data might not match persisted data
146 Clean, // In-memory data matches persisted data
147 CommitError // Error happened during committing
148 };
149
Kun Yi97be3af2019-03-05 22:43:41 -0800150 /* Load the serialized data from sysfile if commit state is dirty.
151 * Returns False if encountered error when loading */
152 bool loadSerializedData();
153
Kun Yi64dc05c2018-12-19 13:19:03 -0800154 std::string baseBlobId_;
Kun Yi0a940b92019-01-07 16:33:11 -0800155 binaryblobproto::BinaryBlobBase blob_;
Kun Yi2765b642019-01-16 11:11:24 -0800156 binaryblobproto::BinaryBlob* currentBlob_ = nullptr;
Kun Yi6baa7132019-01-08 21:21:02 -0800157 bool writable_ = false;
Kun Yi2765b642019-01-16 11:11:24 -0800158 std::unique_ptr<SysFile> file_ = nullptr;
159 uint32_t maxSize_;
Kun Yid297c9f2019-01-09 13:52:30 -0800160 CommitState commitState_ = CommitState::Dirty;
Kun Yi64dc05c2018-12-19 13:19:03 -0800161};
162
Kun Yi68c81142018-12-18 11:17:14 -0800163} // namespace binstore