| 145 | } |
| 146 | |
| 147 | void TChunkedMemoryPool::Absorb(TChunkedMemoryPool&& other) |
| 148 | { |
| 149 | YT_VERIFY(ChunkProvider_ == other.ChunkProvider_); |
| 150 | |
| 151 | OtherBlocks_.reserve(OtherBlocks_.size() + other.OtherBlocks_.size()); |
| 152 | for (auto& block : other.OtherBlocks_) { |
| 153 | OtherBlocks_.push_back(std::move(block)); |
| 154 | } |
| 155 | other.OtherBlocks_.clear(); |
| 156 | |
| 157 | // Suppose that |
| 158 | // - "A" is filled blocks of the current pool; |
| 159 | // - "a" is free blocks of the current pool; |
| 160 | // - "B" is filled blocks of the other pool; |
| 161 | // - "b" is free blocks of the other pool. |
| 162 | // Then, from the initial layouts "AA...Aaa...a" and "BB...Bbb...b" we obtain "BB..BAA..Aaa...abb...b". |
| 163 | Chunks_.reserve(Chunks_.size() + other.Chunks_.size()); |
| 164 | size_t oldSize = Chunks_.size(); |
| 165 | for (auto& chunk : other.Chunks_) { |
| 166 | Chunks_.push_back(std::move(chunk)); |
| 167 | } |
| 168 | // Transform "AA...Aaa...aBB...B" => "BB...BAA...Aaa...a" |
| 169 | std::rotate(Chunks_.begin(), Chunks_.begin() + oldSize, Chunks_.begin() + oldSize + other.NextChunkIndex_); |
| 170 | if (NextChunkIndex_ == 0) { |
| 171 | FreeZoneBegin_ = other.FreeZoneBegin_; |
| 172 | FreeZoneEnd_ = other.FreeZoneEnd_; |
| 173 | } |
| 174 | NextChunkIndex_ += other.NextChunkIndex_; |
| 175 | other.Chunks_.clear(); |
| 176 | other.FreeZoneBegin_ = nullptr; |
| 177 | other.FreeZoneEnd_ = nullptr; |
| 178 | other.NextChunkIndex_ = 0; |
| 179 | |
| 180 | Size_ += other.Size_; |
| 181 | Capacity_ += other.Capacity_; |
| 182 | other.Size_ = 0; |
| 183 | other.Capacity_ = 0; |
| 184 | } |
| 185 | |
| 186 | size_t TChunkedMemoryPool::GetSize() const |
| 187 | { |