mirror of
https://github.com/boostorg/intrusive.git
synced 2026-04-19 07:48:38 +02:00
First inclusion
[SVN r37593]
This commit is contained in:
270
example/doc_assoc_optimized_code.cpp
Normal file
270
example/doc_assoc_optimized_code.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztañaga 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 strings
|
||||
struct 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 objects
|
||||
typedef set<set_base_hook<>::value_traits<Expensive> > Set;
|
||||
typedef unordered_set<unordered_set_base_hook<>::
|
||||
value_traits<Expensive> > UnorderedSet;
|
||||
|
||||
// Search functions
|
||||
Expensive *get_from_set(const char* key, Set &set)
|
||||
{
|
||||
Set::iterator it = set.find(Expensive(key));
|
||||
if( it == set.end() ) return 0;
|
||||
return &*it;
|
||||
}
|
||||
|
||||
Expensive *get_from_unordered_set
|
||||
(const char* key, UnorderedSet &unordered_set)
|
||||
{
|
||||
UnorderedSet::iterator it =
|
||||
unordered_set.find(Expensive (key));
|
||||
if( it == unordered_set.end() ) return 0;
|
||||
return &*it;
|
||||
}
|
||||
//]
|
||||
|
||||
//[doc_assoc_optimized_code_optimized_find
|
||||
// These compare Expensive and a c-string
|
||||
struct 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 functions
|
||||
Expensive *get_from_set_optimized(const char* key, Set &set)
|
||||
{
|
||||
Set::iterator it = set.find(key, StrExpComp());
|
||||
if( it == set.end() ) return 0;
|
||||
return &*it;
|
||||
}
|
||||
|
||||
Expensive *get_from_unordered_set_optimized
|
||||
(const char* key, UnorderedSet &unordered_set)
|
||||
{
|
||||
UnorderedSet::iterator it =
|
||||
unordered_set.find(key, StrHasher(), StrExpEqual());
|
||||
if( it == unordered_set.end() ) return 0;
|
||||
return &*it;
|
||||
}
|
||||
//]
|
||||
|
||||
//[doc_assoc_optimized_code_normal_insert
|
||||
// Insertion functions
|
||||
bool insert_to_set(const char* key, Set &set)
|
||||
{
|
||||
Expensive *pobject = new Expensive(key);
|
||||
bool success = set.insert(*pobject).second;
|
||||
if(!success) delete pobject;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool insert_to_unordered_set
|
||||
(const char* key, UnorderedSet &unordered_set)
|
||||
{
|
||||
Expensive *pobject = new Expensive(key);
|
||||
bool success = unordered_set.insert(*pobject).second;
|
||||
if(!success) delete pobject;
|
||||
return success;
|
||||
}
|
||||
//]
|
||||
|
||||
//[doc_assoc_optimized_code_optimized_insert
|
||||
// Optimized insertion functions
|
||||
bool insert_to_set_optimized(const char* key, Set &set)
|
||||
{
|
||||
Set::insert_commit_data insert_data;
|
||||
bool success = set.insert_check
|
||||
(key, StrExpComp(), insert_data).second;
|
||||
if(success)
|
||||
set.insert_commit(*new Expensive(key), insert_data);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool insert_to_unordered_set_optimized
|
||||
(const char* key, UnorderedSet &unordered_set)
|
||||
{
|
||||
UnorderedSet::insert_commit_data insert_data;
|
||||
bool success = unordered_set.insert_check
|
||||
(key, StrHasher(), StrExpEqual(), insert_data).second;
|
||||
if(success)
|
||||
unordered_set.insert_commit(*new Expensive(key), insert_data);
|
||||
return success;
|
||||
}
|
||||
//]
|
||||
|
||||
int main()
|
||||
{
|
||||
Set set;
|
||||
UnorderedSet::bucket_type buckets[10];
|
||||
UnorderedSet unordered_set(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_unordered_set(expensive_key, unordered_set)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(get_from_set_optimized(expensive_key, set)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(get_from_unordered_set_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_unordered_set(expensive_key, unordered_set)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!get_from_set_optimized(expensive_key, set)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!get_from_unordered_set_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_unordered_set(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_unordered_set_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_unordered_set(expensive_key, unordered_set)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(insert_to_set_optimized(expensive_key, set)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(insert_to_unordered_set_optimized(expensive_key, unordered_set)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
set.erase(value);
|
||||
unordered_set.erase(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user