doc_assoc_optimized_code.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 261 行

CPP
261
字号
///////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga  2006-2007//// Distributed under the Boost Software License, Version 1.0.//    (See accompanying file LICENSE_1_0.txt or copy at//          http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/intrusive for documentation./////////////////////////////////////////////////////////////////////////////////[doc_assoc_optimized_code_normal_find#include <boost/intrusive/set.hpp>#include <boost/intrusive/unordered_set.hpp>#include <cstring>using namespace boost::intrusive;// Hash function for stringsstruct StrHasher{   std::size_t operator()(const char *str) const   {        std::size_t seed = 0;      for(; *str; ++str)   boost::hash_combine(seed, *str);      return seed;   }};class Expensive : public set_base_hook<>, public unordered_set_base_hook<>{   std::string key_;   // Other members...     public:   Expensive(const char *key)      :  key_(key)      {}  //other expensive initializations...   const std::string & get_key() const      {  return key_;   }   friend bool operator <  (const Expensive &a, const Expensive &b)      {  return a.key_ < b.key_;  }   friend bool operator == (const Expensive &a, const Expensive &b)      {  return a.key_ == b.key_;  }   friend std::size_t hash_value(const Expensive &object)      {  return StrHasher()(object.get_key().c_str());  }};// A set and unordered_set that store Expensive objectstypedef set<Expensive>           Set;typedef unordered_set<Expensive> UnorderedSet;// Search functionsExpensive *get_from_set(const char* key, Set &set_object){   Set::iterator it = set_object.find(Expensive(key));   if( it == set_object.end() )     return 0;   return &*it;}Expensive *get_from_uset(const char* key, UnorderedSet &uset_object){   UnorderedSet::iterator it = uset_object.find(Expensive (key));   if( it == uset_object.end() )  return 0;   return &*it;}//]//[doc_assoc_optimized_code_optimized_find// These compare Expensive and a c-stringstruct StrExpComp{   bool operator()(const char *str, const Expensive &c) const   {  return std::strcmp(str, c.get_key().c_str()) < 0;  }   bool operator()(const Expensive &c, const char *str) const   {  return std::strcmp(c.get_key().c_str(), str) < 0;  }};struct StrExpEqual{   bool operator()(const char *str, const Expensive &c) const   {  return std::strcmp(str, c.get_key().c_str()) == 0;  }   bool operator()(const Expensive &c, const char *str) const   {  return std::strcmp(c.get_key().c_str(), str) == 0;  }};// Optimized search functionsExpensive *get_from_set_optimized(const char* key, Set &set_object){   Set::iterator it = set_object.find(key, StrExpComp());   if( it == set_object.end() )   return 0;   return &*it;}Expensive *get_from_uset_optimized(const char* key, UnorderedSet &uset_object){   UnorderedSet::iterator it = uset_object.find(key, StrHasher(), StrExpEqual());   if( it == uset_object.end() )  return 0;   return &*it;}//]//[doc_assoc_optimized_code_normal_insert// Insertion functionsbool insert_to_set(const char* key, Set &set_object){   Expensive *pobject = new Expensive(key);   bool success = set_object.insert(*pobject).second;   if(!success)   delete pobject;   return success;}bool insert_to_uset(const char* key, UnorderedSet &uset_object){   Expensive *pobject = new Expensive(key);   bool success = uset_object.insert(*pobject).second;   if(!success)   delete pobject;   return success;}//]//[doc_assoc_optimized_code_optimized_insert// Optimized insertion functionsbool insert_to_set_optimized(const char* key, Set &set_object){   Set::insert_commit_data insert_data;   bool success = set_object.insert_check(key, StrExpComp(), insert_data).second;   if(success) set_object.insert_commit(*new Expensive(key), insert_data);   return success;}bool insert_to_uset_optimized(const char* key, UnorderedSet &uset_object){   UnorderedSet::insert_commit_data insert_data;   bool success = uset_object.insert_check      (key, StrHasher(), StrExpEqual(), insert_data).second;   if(success) uset_object.insert_commit(*new Expensive(key), insert_data);   return success;}//]int main(){   Set set;   UnorderedSet::bucket_type buckets[10];   UnorderedSet unordered_set(UnorderedSet::bucket_traits(buckets, 10));   const char * const expensive_key      = "A long string that avoids small string optimization";   Expensive value(expensive_key);   if(get_from_set(expensive_key, set)){      return 1;   }   if(get_from_uset(expensive_key, unordered_set)){      return 1;   }   if(get_from_set_optimized(expensive_key, set)){      return 1;   }   if(get_from_uset_optimized(expensive_key, unordered_set)){      return 1;   }   Set::iterator setit =  set.insert(value).first;   UnorderedSet::iterator unordered_setit =  unordered_set.insert(value).first;   if(!get_from_set(expensive_key, set)){      return 1;   }   if(!get_from_uset(expensive_key, unordered_set)){      return 1;   }   if(!get_from_set_optimized(expensive_key, set)){      return 1;   }   if(!get_from_uset_optimized(expensive_key, unordered_set)){      return 1;   }   set.erase(setit);   unordered_set.erase(unordered_setit);   if(!insert_to_set(expensive_key, set)){      return 1;   }   if(!insert_to_uset(expensive_key, unordered_set)){      return 1;   }   {      Expensive *ptr = &*set.begin();      set.clear();      delete ptr;   }   {      Expensive *ptr = &*unordered_set.begin();      unordered_set.clear();      delete ptr;   }   if(!insert_to_set_optimized(expensive_key, set)){      return 1;   }   if(!insert_to_uset_optimized(expensive_key, unordered_set)){      return 1;   }   {      Expensive *ptr = &*set.begin();      set.clear();      delete ptr;   }   {      Expensive *ptr = &*unordered_set.begin();      unordered_set.clear();      delete ptr;   }   setit       =  set.insert(value).first;   unordered_setit   =  unordered_set.insert(value).first;   if(insert_to_set(expensive_key, set)){      return 1;   }   if(insert_to_uset(expensive_key, unordered_set)){      return 1;   }   if(insert_to_set_optimized(expensive_key, set)){      return 1;   }   if(insert_to_uset_optimized(expensive_key, unordered_set)){      return 1;   }   set.erase(value);   unordered_set.erase(value);   return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?