LevelDB 之 arena
生活随笔
收集整理的這篇文章主要介紹了
LevelDB 之 arena
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
粒度比較大,實現簡潔清晰明了。
對比nginx的,nginx從小到大各種尺寸都有,適用性更好一些。相對要精細很多。
Arena.h
//z 2014-06-05 10:48:50 L.209'47470 BG57IV3 T1840949363.K.F1370514324[T6,L108,R4,V118]
// Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors.#ifndef STORAGE_LEVELDB_UTIL_ARENA_H_ #define STORAGE_LEVELDB_UTIL_ARENA_H_#include <cstddef> #include <vector> #include <assert.h> #include <stdint.h>namespace leveldb { /*//z 思路: 先在上一次分配的內存塊中查找是否剩余空間能否容納當前申請的空間;如果足以容納,直接使用剩余空間 否則視其大小重新分配一塊空間:如果大于1024,直接分配一塊新空間,大小與申請空間大小同 如果小于1024,說明上一塊空間剩余空間小于1024,那么重新分配一塊4096大小的空間,使用該空間來存放待申請的空間 */ class Arena { public:Arena();~Arena();// Return a pointer to a newly allocated memory block of "bytes" bytes.char* Allocate(size_t bytes);// Allocate memory with the normal alignment guarantees provided by mallocchar* AllocateAligned(size_t bytes);// Returns an estimate of the total memory usage of data allocated// by the arena (including space allocated but not yet used for user// allocations).size_t MemoryUsage() const{return blocks_memory_ + blocks_.capacity() * sizeof(char*);}private:char* AllocateFallback(size_t bytes);char* AllocateNewBlock(size_t block_bytes);// Allocation statechar* alloc_ptr_;size_t alloc_bytes_remaining_;// Array of new[] allocated memory blocksstd::vector<char*> blocks_;// Bytes of memory in blocks allocated so farsize_t blocks_memory_;// No copying allowedArena(const Arena&);void operator=(const Arena&); };inline char* Arena::Allocate(size_t bytes) {// The semantics of what to return are a bit messy if we allow// 0-byte allocations, so we disallow them here (we don't need// them for our internal use).assert(bytes > 0);//z 在一塊直接分配好的內存上移動一下指針即可;事實上可能會存在很多的浪費。if (bytes <= alloc_bytes_remaining_){char* result = alloc_ptr_;alloc_ptr_ += bytes;alloc_bytes_remaining_ -= bytes;return result;}//z 如果剩余控件不足與容納,那么根據bytes大小決定是否重新分配一塊標準大小的內存(4096),或者要是bytes大于1024,直接//z 分配其大小的內存,原標準塊內存仍舊有用。//z 如果小于 1024 ,說明原標準塊剩余內存不足以容納1024,新分配一塊標準塊內存,用此來為bytes分配對應內存。return AllocateFallback(bytes); }}#endif // STORAGE_LEVELDB_UTIL_ARENA_H_
//z 2014-06-05 10:48:50 L.209'47470 BG57IV3 T1840949363.K.F1370514324[T6,L108,R4,V118]
arena.cc
// Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors.#include "util/arena.h" #include <assert.h>namespace leveldb {//z 常量變量名k開頭static const int kBlockSize = 4096;//z 初始化Arena::Arena() {blocks_memory_ = 0;alloc_ptr_ = NULL; // First allocation will allocate a blockalloc_bytes_remaining_ = 0;}Arena::~Arena() {//z 刪除申請的內存for (size_t i = 0; i < blocks_.size(); i++) {delete[] blocks_[i];}}char* Arena::AllocateFallback(size_t bytes) {//z 如果申請的bytes > 1024if (bytes > kBlockSize / 4) {// Object is more than a quarter of our block size. Allocate it separately// to avoid wasting too much space in leftover bytes.char* result = AllocateNewBlock(bytes);return result;}// We waste the remaining space in the current block.//z 不大于1024時,分配一塊標準大小的內存alloc_ptr_ = AllocateNewBlock(kBlockSize);alloc_bytes_remaining_ = kBlockSize;//z 指定返回的位置char* result = alloc_ptr_;//z 移動指針位置至空閑內存開始的地方alloc_ptr_ += bytes;//z 記錄還剩下多少內存alloc_bytes_remaining_ -= bytes;return result;}char* Arena::AllocateAligned(size_t bytes) {//z 這個值是固定的,不用每次都求一次?但是代價非常小,求一次也無所為?const int align = sizeof(void*); // We'll align to pointer sizeassert((align & (align-1)) == 0); // Pointer size should be a power of 2//z 求的其余數size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align-1);size_t slop = (current_mod == 0 ? 0 : align - current_mod);size_t needed = bytes + slop;char* result;//z 如果剩余的空間足以容納所需要的內存if (needed <= alloc_bytes_remaining_) {//z 對齊返回地址result = alloc_ptr_ + slop;alloc_ptr_ += needed;alloc_bytes_remaining_ -= needed;} else {// AllocateFallback always returned aligned memory//z 否則直接分配一塊新的內存//z 在這種情況下這塊內存可能很小result = AllocateFallback(bytes);}//z 確保返回地址是對齊的assert((reinterpret_cast<uintptr_t>(result) & (align-1)) == 0);return result;}//z 在不小于一個page的時候,直接采用這種方式char* Arena::AllocateNewBlock(size_t block_bytes) {char* result = new char[block_bytes];blocks_memory_ += block_bytes;blocks_.push_back(result);return result;}} //z 2014-06-05 10:48:50 L.209'47470 BG57IV3 T1840949363.K.F1370514324[T6,L108,R4,V118]
對比nginx的,nginx從小到大各種尺寸都有,適用性更好一些。相對要精細很多。
Arena.h
//z 2014-06-05 10:48:50 L.209'47470 BG57IV3 T1840949363.K.F1370514324[T6,L108,R4,V118]
// Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors.#ifndef STORAGE_LEVELDB_UTIL_ARENA_H_ #define STORAGE_LEVELDB_UTIL_ARENA_H_#include <cstddef> #include <vector> #include <assert.h> #include <stdint.h>namespace leveldb { /*//z 思路: 先在上一次分配的內存塊中查找是否剩余空間能否容納當前申請的空間;如果足以容納,直接使用剩余空間 否則視其大小重新分配一塊空間:如果大于1024,直接分配一塊新空間,大小與申請空間大小同 如果小于1024,說明上一塊空間剩余空間小于1024,那么重新分配一塊4096大小的空間,使用該空間來存放待申請的空間 */ class Arena { public:Arena();~Arena();// Return a pointer to a newly allocated memory block of "bytes" bytes.char* Allocate(size_t bytes);// Allocate memory with the normal alignment guarantees provided by mallocchar* AllocateAligned(size_t bytes);// Returns an estimate of the total memory usage of data allocated// by the arena (including space allocated but not yet used for user// allocations).size_t MemoryUsage() const{return blocks_memory_ + blocks_.capacity() * sizeof(char*);}private:char* AllocateFallback(size_t bytes);char* AllocateNewBlock(size_t block_bytes);// Allocation statechar* alloc_ptr_;size_t alloc_bytes_remaining_;// Array of new[] allocated memory blocksstd::vector<char*> blocks_;// Bytes of memory in blocks allocated so farsize_t blocks_memory_;// No copying allowedArena(const Arena&);void operator=(const Arena&); };inline char* Arena::Allocate(size_t bytes) {// The semantics of what to return are a bit messy if we allow// 0-byte allocations, so we disallow them here (we don't need// them for our internal use).assert(bytes > 0);//z 在一塊直接分配好的內存上移動一下指針即可;事實上可能會存在很多的浪費。if (bytes <= alloc_bytes_remaining_){char* result = alloc_ptr_;alloc_ptr_ += bytes;alloc_bytes_remaining_ -= bytes;return result;}//z 如果剩余控件不足與容納,那么根據bytes大小決定是否重新分配一塊標準大小的內存(4096),或者要是bytes大于1024,直接//z 分配其大小的內存,原標準塊內存仍舊有用。//z 如果小于 1024 ,說明原標準塊剩余內存不足以容納1024,新分配一塊標準塊內存,用此來為bytes分配對應內存。return AllocateFallback(bytes); }}#endif // STORAGE_LEVELDB_UTIL_ARENA_H_
//z 2014-06-05 10:48:50 L.209'47470 BG57IV3 T1840949363.K.F1370514324[T6,L108,R4,V118]
arena.cc
// Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors.#include "util/arena.h" #include <assert.h>namespace leveldb {//z 常量變量名k開頭static const int kBlockSize = 4096;//z 初始化Arena::Arena() {blocks_memory_ = 0;alloc_ptr_ = NULL; // First allocation will allocate a blockalloc_bytes_remaining_ = 0;}Arena::~Arena() {//z 刪除申請的內存for (size_t i = 0; i < blocks_.size(); i++) {delete[] blocks_[i];}}char* Arena::AllocateFallback(size_t bytes) {//z 如果申請的bytes > 1024if (bytes > kBlockSize / 4) {// Object is more than a quarter of our block size. Allocate it separately// to avoid wasting too much space in leftover bytes.char* result = AllocateNewBlock(bytes);return result;}// We waste the remaining space in the current block.//z 不大于1024時,分配一塊標準大小的內存alloc_ptr_ = AllocateNewBlock(kBlockSize);alloc_bytes_remaining_ = kBlockSize;//z 指定返回的位置char* result = alloc_ptr_;//z 移動指針位置至空閑內存開始的地方alloc_ptr_ += bytes;//z 記錄還剩下多少內存alloc_bytes_remaining_ -= bytes;return result;}char* Arena::AllocateAligned(size_t bytes) {//z 這個值是固定的,不用每次都求一次?但是代價非常小,求一次也無所為?const int align = sizeof(void*); // We'll align to pointer sizeassert((align & (align-1)) == 0); // Pointer size should be a power of 2//z 求的其余數size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align-1);size_t slop = (current_mod == 0 ? 0 : align - current_mod);size_t needed = bytes + slop;char* result;//z 如果剩余的空間足以容納所需要的內存if (needed <= alloc_bytes_remaining_) {//z 對齊返回地址result = alloc_ptr_ + slop;alloc_ptr_ += needed;alloc_bytes_remaining_ -= needed;} else {// AllocateFallback always returned aligned memory//z 否則直接分配一塊新的內存//z 在這種情況下這塊內存可能很小result = AllocateFallback(bytes);}//z 確保返回地址是對齊的assert((reinterpret_cast<uintptr_t>(result) & (align-1)) == 0);return result;}//z 在不小于一個page的時候,直接采用這種方式char* Arena::AllocateNewBlock(size_t block_bytes) {char* result = new char[block_bytes];blocks_memory_ += block_bytes;blocks_.push_back(result);return result;}} //z 2014-06-05 10:48:50 L.209'47470 BG57IV3 T1840949363.K.F1370514324[T6,L108,R4,V118]
轉載于:https://www.cnblogs.com/IS2120/p/6745654.html
總結
以上是生活随笔為你收集整理的LevelDB 之 arena的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UML的奥妙 - 学习UML笔记(1)
- 下一篇: 人工智能的未来是否真的会成为工人的乌托邦