Advertisement
Guest User

Untitled

a guest
Apr 27th, 2015
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.75 KB | None | 0 0
  1. #include <string>
  2. #include <unordered_set>
  3.  
  4. #include <boost/intrusive_ptr.hpp>
  5. #include <boost/noncopyable.hpp>
  6.  
  7. #include <gperftools/malloc_extension.h>
  8.  
  9. #include <assert.h>
  10. #include <string.h>
  11.  
  12. class Item : boost::noncopyable
  13. {
  14. public:
  15. Item(const char* key,
  16. uint32_t flags,
  17. int valuelen,
  18. uint64_t cas)
  19. : keylen_(strlen(key)),
  20. valuelen_(valuelen),
  21. cas_(cas)
  22. {
  23. char buf[64];
  24. flaglen_ = snprintf(buf, sizeof buf, " %u %d\r\n", flags, valuelen);
  25. data_ = static_cast<char*>(::malloc(totalLen()));
  26. memcpy(data_, key, keylen_);
  27. memcpy(data_ + keylen_, buf, flaglen_);
  28. data_[totalLen() - 2] = '\r';
  29. data_[totalLen() - 1] = '\n';
  30. }
  31.  
  32. ~Item()
  33. {
  34. ::free(data_);
  35. }
  36.  
  37. void assign(const char* value, int valuelen)
  38. {
  39. assert(valuelen <= valuelen_);
  40. memcpy(data_ + keylen_ + flaglen_, value, valuelen);
  41. }
  42.  
  43. size_t hash() const
  44. {
  45. return std::_Hash_impl::hash(data_, keylen_);
  46. }
  47.  
  48. bool equals(const Item& rhs) const
  49. {
  50. return keylen_ == rhs.keylen_ && memcmp(data_, rhs.data_, keylen_) == 0;
  51. }
  52.  
  53. int inc_ref() const
  54. {
  55. return ++refcount_;
  56. }
  57.  
  58. int dec_ref() const
  59. {
  60. return --refcount_;
  61. }
  62.  
  63. private:
  64.  
  65. int totalLen() const
  66. {
  67. return keylen_ + flaglen_ + valuelen_ + 2;
  68. }
  69.  
  70. const uint8_t keylen_;
  71. uint8_t flaglen_ = 0;
  72. mutable uint16_t refcount_ = 0;
  73. const int valuelen_;
  74. const uint64_t cas_;
  75. char* data_ = nullptr;
  76. };
  77.  
  78. typedef boost::intrusive_ptr<const Item> ConstItemPtr;
  79.  
  80. void intrusive_ptr_add_ref(const Item* p)
  81. {
  82. if (p->inc_ref() == 0)
  83. assert(false && "refcount overflow");
  84. }
  85.  
  86. void intrusive_ptr_release(const Item* p)
  87. {
  88. if (p->dec_ref() == 0)
  89. delete p;
  90. }
  91.  
  92. struct Hash
  93. {
  94. size_t operator()(const ConstItemPtr& x) const
  95. {
  96. return x->hash();
  97. }
  98. };
  99.  
  100. struct Equal
  101. {
  102. bool operator()(const ConstItemPtr& x, const ConstItemPtr& y) const
  103. {
  104. return x->equals(*y);
  105. }
  106. };
  107.  
  108. typedef std::unordered_set<ConstItemPtr, Hash, Equal> Map;
  109.  
  110. int main(int argc, char* argv[])
  111. {
  112. MallocExtension::Initialize();
  113.  
  114. int items = argc > 1 ? atoi(argv[1]) : 1000 * 1000;
  115. int keylen = 10;
  116. int valuelen = 100;
  117. char key[256] = { 0 };
  118. std::string value;
  119. Map theMap;
  120. for (int i = 0; i < items; ++i)
  121. {
  122. snprintf(key, sizeof key, "%0*d", keylen, i);
  123. value.assign(valuelen, "0123456789"[i % 10]);
  124. boost::intrusive_ptr<Item> item(new Item(key, 0, valuelen, 1));
  125. item->assign(value.data(), value.size());
  126. auto result = theMap.insert(std::move(item));
  127. assert(result.second);
  128. }
  129.  
  130. printf("sizeof Item = %zd\n", sizeof(Item));
  131. printf("sizeof intrusive_ptr = %zd\n", sizeof(boost::intrusive_ptr<Item>));
  132. printf("items = %zd\n", theMap.size());
  133.  
  134. char buf[65536] = "";
  135. MallocExtension::instance()->GetStats(buf, sizeof buf);
  136. printf("%s\n", buf);
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement