@@ -40,7 +40,8 @@ std::unique_ptr<SpaceLayout> MakeSpaceLayout(const bool tempDumpDirEnable)
4040}
4141
4242Status SpaceManager::Setup (const std::vector<std::string>& storageBackends, const size_t blockSize,
43- const bool tempDumpDirEnable)
43+ const bool tempDumpDirEnable, const size_t storageCapacity,
44+ const bool recycleEnable, const float recycleThresholdRatio)
4445{
4546 if (blockSize == 0 ) {
4647 UC_ERROR (" Invalid block size({})." , blockSize);
@@ -50,20 +51,34 @@ Status SpaceManager::Setup(const std::vector<std::string>& storageBackends, cons
5051 if (!this ->layout_ ) { return Status::OutOfMemory (); }
5152 auto status = this ->layout_ ->Setup (storageBackends);
5253 if (status.Failure ()) { return status; }
54+ status = this ->property_ .Setup (this ->layout_ ->ClusterPropertyFilePath ());
55+ if (recycleEnable && storageCapacity > 0 ) {
56+ auto totalBlocks = storageCapacity / blockSize;
57+ status = this ->recycle_ .Setup (this ->GetSpaceLayout (), totalBlocks, [this ] {
58+ this ->property_ .DecreaseCapacity (this ->blockSize_ );
59+ });
60+ if (status.Failure ()) { return status; }
61+ }
62+ if (status.Failure ()) { return status; }
5363 this ->blockSize_ = blockSize;
64+ this ->capacity_ = storageCapacity;
65+ this ->recycleEnable_ = recycleEnable;
66+ this ->capacityRecycleThreshold_ = static_cast <size_t >(storageCapacity * recycleThresholdRatio);
5467 return Status::OK ();
5568}
5669
57- Status SpaceManager::NewBlock (const std::string& blockId) const
70+ Status SpaceManager::NewBlock (const std::string& blockId)
5871{
72+ Status status = this ->CapacityCheck ();
73+ if (status.Failure ()) { return status; }
5974 constexpr auto activated = true ;
6075 auto parent = File::Make (this ->layout_ ->DataFileParent (blockId, activated));
6176 auto file = File::Make (this ->layout_ ->DataFilePath (blockId, activated));
6277 if (!parent || !file) {
6378 UC_ERROR (" Failed to new block({})." , blockId);
6479 return Status::OutOfMemory ();
6580 }
66- auto status = parent->MkDir ();
81+ status = parent->MkDir ();
6782 if (status == Status::DuplicateKey ()) { status = Status::OK (); }
6883 if (status.Failure ()) {
6984 UC_ERROR (" Failed({}) to new block({})." , status, blockId);
@@ -88,10 +103,11 @@ Status SpaceManager::NewBlock(const std::string& blockId) const
88103 UC_ERROR (" Failed({}) to new block({})." , status, blockId);
89104 return status;
90105 }
106+ this ->property_ .IncreaseCapacity (this ->blockSize_ );
91107 return Status::OK ();
92108}
93109
94- Status SpaceManager::CommitBlock (const std::string& blockId, bool success) const
110+ Status SpaceManager::CommitBlock (const std::string& blockId, bool success)
95111{
96112 const auto activatedParent = this ->layout_ ->DataFileParent (blockId, true );
97113 const auto activatedFile = this ->layout_ ->DataFilePath (blockId, true );
@@ -112,6 +128,7 @@ Status SpaceManager::CommitBlock(const std::string& blockId, bool success) const
112128 if (status.Failure ()) {
113129 UC_ERROR (" Failed({}) to {} block({})." , status, success ? " commit" : " cancel" , blockId);
114130 }
131+ this ->property_ .DecreaseCapacity (this ->blockSize_ );
115132 return status;
116133}
117134
@@ -136,4 +153,20 @@ bool SpaceManager::LookupBlock(const std::string& blockId) const
136153
137154const SpaceLayout* SpaceManager::GetSpaceLayout () const { return this ->layout_ .get (); }
138155
156+ Status SpaceManager::CapacityCheck ()
157+ {
158+ if (this ->capacity_ == 0 ) { return Status::OK (); }
159+
160+ const size_t used = this ->property_ .GetCapacity ();
161+ if (this ->recycleEnable_ && used >= this ->capacityRecycleThreshold_ ) {
162+ this ->recycle_ .Trigger ();
163+ }
164+ if (used > this ->capacity_ - this ->blockSize_ ) {
165+ UC_ERROR (" Capacity is not enough, capacity: {}, current: {}, block size: {}." ,
166+ this ->capacity_ , used, this ->blockSize_ );
167+ return Status::NoSpace ();
168+ }
169+ return Status::OK ();
170+ }
171+
139172} // namespace UC
0 commit comments