日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Rocksdb Slice使用中的一个小坑

發布時間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Rocksdb Slice使用中的一个小坑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文記錄一下使用Rocksdb Slice過程中的一個小小坑,差點沒一口老血吐出來。

rocksdb的Slice 數據結構是一個小型得不可變類string數據結構,設計出來的目的是為了保證rocksdb內部處理用戶輸入的key在從內存到持久化磁盤的整個處理鏈路是不會被修改的,比較方便得從user_key 解碼出internal_key

如果把這個數據結構當作普通字符串來使用,會有意想不到的 收獲

Slice數據結構代碼如下:

class Slice {public:// Create an empty slice.Slice() : data_(""), size_(0) {}// Create a slice that refers to d[0,n-1].Slice(const char* d, size_t n) : data_(d), size_(n) {}// Create a slice that refers to the contents of "s"/* implicit */Slice(const std::string& s) : data_(s.data()), size_(s.size()) {}#ifdef __cpp_lib_string_view// Create a slice that refers to the same contents as "sv"/* implicit */Slice(std::string_view sv) : data_(sv.data()), size_(sv.size()) {}
#endif// Create a slice that refers to s[0,strlen(s)-1]/* implicit */Slice(const char* s) : data_(s) {cout << "called Slice(const char* s)" << endl;size_ = (s == nullptr) ? 0 : strlen(s); }// Create a single slice from SliceParts using buf as storage.// buf must exist as long as the returned Slice exists.Slice(const struct SliceParts& parts, std::string* buf);// Return a pointer to the beginning of the referenced dataconst char* data() const { return data_; }// Return the length (in bytes) of the referenced datasize_t size() const { return size_; }// Return true iff the length of the referenced data is zerobool empty() const { return size_ == 0; }// Return the ith byte in the referenced data.// REQUIRES: n < size()char operator[](size_t n) const {assert(n < size());return data_[n];}...// Return a string that contains the copy of the referenced data.// when hex is true, returns a string of twice the length hex encoded (0-9A-F)// Return a string that contains the copy of the referenced data.std::string ToString(bool hex = false) const {std::string result;  // RVO/NRVO/moveif (hex) {result.reserve(2 * size_);for (size_t i = 0; i < size_; ++i) {unsigned char c = data_[i];result.push_back(toHex(c >> 4));result.push_back(toHex(c & 0xf));}return result;} else {result.assign(data_, size_);return result;}}	......// Compare two slices and returns the first byte where they differsize_t difference_offset(const Slice& b) const;// private: make these public for rocksdbjni accessconst char* data_;size_t size_;// Intentionally copyable
};

主要是其維護了一個const char* data_成員變量,當我們用戶通過db->Put(opts, "key","value",)時會調用Slice(const std::string& s)構造函數,并不會維護一個新的存儲空間,而是使用本來的默認構造函數為data_分配的地址空間。

坑就來了,也就是想要通過如下方式創建一個新的Slice變量:

map<Slice,int, MetaCmp> mp;
void AddSlice(const Slice& buf, const int& value) {if(mp.find(buf) != mp.end()) {mp[buf] = value;} else {mp.insert(pair<Slice, int>(buf, value));}
}int main() {for(int i = 0;i < 10; i++) {Slice str("meta" + to_string(i));AddSlice(str, i);}return 0;
}

會發現每次創建的Slice都會放在一個地址中,你以為你創建了9個Slice,并且存放到了一個map中,但實際上Slice的數據地址其實只有一個內容。

called default constructor 0x10e756290
called Slice(const std::string& s) meta0 0x7ffee14b5738
called Slice(const std::string& s) meta1 0x7ffee14b5738
called Slice(const std::string& s) meta2 0x7ffee14b5738
called Slice(const std::string& s) meta3 0x7ffee14b5738
called Slice(const std::string& s) meta4 0x7ffee14b5738
called Slice(const std::string& s) meta5 0x7ffee14b5738
called Slice(const std::string& s) meta6 0x7ffee14b5738
called Slice(const std::string& s) meta7 0x7ffee14b5738
called Slice(const std::string& s) meta8 0x7ffee14b5738
called Slice(const std::string& s) meta9 0x7ffee14b5738
key: meta9 value: 9

也就是當我們調用Slice str("meta" + to_string(i));構造一個str對象時,實際存放數據的內存空間內容就已經被修改了,后續的AddSlice函數已經其內部添加到一個map中的操作其實都是在針對已存在的key進行的操作。

歸根結底就是其維護了一個const char* data_;成員變量,它約束了當我們啟動一個進程時data_指針指向的內容只能是常量區域的一個固定的地址,并不會為各位新開辟一個存儲空間。

以上代碼切換成我們的string 時,則每一次構造都會重新分配一個新的地址來存放我們的內容。

坑~~~

總結

以上是生活随笔為你收集整理的Rocksdb Slice使用中的一个小坑的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。