00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __PION_EVENT_HEADER__
00021 #define __PION_EVENT_HEADER__
00022
00023 #include <list>
00024 #include <vector>
00025 #include <boost/bind.hpp>
00026 #include <boost/function.hpp>
00027 #ifdef _MSC_VER
00028 #pragma warning(push)
00029 #pragma warning(disable: 4181) // qualifier applied to reference type
00030 #endif
00031 #include <boost/variant.hpp>
00032 #ifdef _MSC_VER
00033 #pragma warning(pop)
00034 #endif
00035 #include <boost/thread/once.hpp>
00036 #include <boost/thread/mutex.hpp>
00037 #include <boost/utility/enable_if.hpp>
00038 #include <boost/detail/atomic_count.hpp>
00039 #include <boost/iterator/iterator_facade.hpp>
00040 #include <boost/intrusive/rbtree_algorithms.hpp>
00041 #include <pion/PionConfig.hpp>
00042 #include <pion/PionBlob.hpp>
00043 #include <pion/PionDateTime.hpp>
00044 #include <pion/platform/Vocabulary.hpp>
00045
00046
00048 #ifndef _WIN64
00049 #define PION_EVENT_USE_POOL_ALLOCATORS
00050 #endif
00051
00052 #ifdef PION_EVENT_USE_POOL_ALLOCATORS
00053 #include <boost/thread/tss.hpp>
00054 #include <pion/PionPoolAllocator.hpp>
00055 #else
00056 #include <cstdlib>
00057 #endif
00058
00059
00060 namespace pion {
00061 namespace platform {
00062
00063
00067 template <typename CharType, typename AllocType>
00068 class BasicEvent
00069 : private boost::noncopyable
00070 {
00071 public:
00072
00074 struct ParameterNode;
00075
00077 class TermTypeNotSerializableException : public std::exception {
00078 public:
00079 virtual const char* what() const throw() {
00080 return "Term type is not serializable";
00081 }
00082 };
00083
00084
00085 protected:
00086
00088 template <typename NodeType>
00089 class IteratorBase :
00090 public boost::iterator_facade<IteratorBase<NodeType>, NodeType,
00091 boost::bidirectional_traversal_tag>
00092 {
00093 private:
00094
00096 struct enabler {};
00097
00098 public:
00099
00101 IteratorBase(void) { tree_algo::init(&m_param_ptr); }
00102
00104 explicit IteratorBase(NodeType *p) : m_param_ptr(p) {}
00105
00107 template <class OtherNodeType>
00108 IteratorBase(IteratorBase<OtherNodeType> const& other,
00109 typename boost::enable_if<
00110 boost::is_convertible<OtherNodeType*,NodeType*>,
00111 enabler>::type = enabler()
00112 )
00113 : m_param_ptr(other.m_param_ptr)
00114 {}
00115
00116 private:
00117
00119 inline void increment(void) {
00120 m_param_ptr = tree_algo::next_node(const_cast<ParameterNode*>(m_param_ptr));
00121 }
00122
00124 inline void decrement(void) {
00125 m_param_ptr = tree_algo::prev_node(const_cast<ParameterNode*>(m_param_ptr));
00126 }
00127
00129 template <class OtherValue>
00130 inline bool equal(IteratorBase<OtherValue> const& other) const {
00131 return this->m_param_ptr == other.m_param_ptr;
00132 }
00133
00135 NodeType& dereference(void) const {
00136 return *m_param_ptr;
00137 }
00138
00140 friend class boost::iterator_core_access;
00141
00144 friend class IteratorBase<const ParameterNode>;
00145 friend class IteratorBase<ParameterNode>;
00146
00148 NodeType * m_param_ptr;
00149 };
00150
00151
00152 public:
00153
00155 typedef Vocabulary::TermRef EventType;
00156
00158 typedef PionBlob<CharType,AllocType> BlobType;
00159
00161 typedef typename BlobType::BlobParams BlobParams;
00162
00168 typedef boost::variant<boost::int32_t, boost::uint32_t,
00169 boost::int64_t, boost::uint64_t, float, double, long double,
00170 PionDateTime, BlobType> ParameterValue;
00171
00177 struct ParameterNode {
00179 ParameterNode(void) {}
00180
00182 template <typename T>
00183 ParameterNode(const Vocabulary::TermRef& tr, const T& v) :
00184 term_ref(tr), value(v)
00185 {}
00186
00188 ParameterNode * m_parent_ptr;
00190 ParameterNode * m_left_ptr;
00192 ParameterNode * m_right_ptr;
00194 boost::uint8_t m_tree_color;
00195
00197 Vocabulary::TermRef term_ref;
00198
00200 ParameterValue value;
00201 };
00202
00204 typedef IteratorBase<ParameterNode> Iterator;
00205
00207 typedef IteratorBase<ParameterNode const> ConstIterator;
00208
00210 typedef std::pair<ConstIterator, ConstIterator>
00211 ValuesRange;
00212
00219 BasicEvent(const EventType t, AllocType *alloc_ptr)
00220 : m_event_type(t), m_alloc_ptr(alloc_ptr), m_references(0)
00221 {
00222
00223 tree_algo::init_header(&m_param_tree);
00224 }
00225
00227 ~BasicEvent() { clear(); }
00228
00230 inline EventType getType(void) const { return m_event_type; }
00231
00233 inline bool empty(void) const {
00234 return (tree_algo::begin_node(&m_param_tree) == &m_param_tree);
00235 }
00236
00238 inline ConstIterator begin(void) const {
00239 return ConstIterator(tree_algo::begin_node(&m_param_tree));
00240 }
00241
00243 inline ConstIterator end(void) const {
00244 return ConstIterator(tree_algo::end_node(&m_param_tree));
00245 }
00246
00248 inline void clear(void) {
00249 tree_algo::clear_and_dispose(&m_param_tree,
00250 boost::bind(&BasicEvent<CharType,AllocType>::destroyParameter, this, _1));
00251 }
00252
00258 inline void clear(const Vocabulary::TermRef& term_ref) {
00259 ParameterNode *node_ptr;
00260 std::pair<ParameterNode*, ParameterNode*> range =
00261 tree_algo::equal_range(&m_param_tree, term_ref, m_key_compare);
00262 while (range.first != range.second) {
00263 node_ptr = range.first;
00264 range.first = tree_algo::next_node(range.first);
00265 tree_algo::erase(&m_param_tree, node_ptr);
00266 destroyParameter(node_ptr);
00267 }
00268 }
00269
00276 inline ConstIterator find(const Vocabulary::TermRef& term_ref) const {
00277 return ConstIterator(tree_algo::find(&m_param_tree, term_ref, m_key_compare));
00278 }
00279
00287 inline ValuesRange equal_range(const Vocabulary::TermRef& term_ref) const
00288 {
00289 std::pair<ParameterNode*, ParameterNode*> range =
00290 tree_algo::equal_range(&m_param_tree, term_ref, m_key_compare);
00291 return std::make_pair(Iterator(range.first), Iterator(range.second));
00292 }
00293
00299 inline void for_each(boost::function2<void, Vocabulary::TermRef, const ParameterValue&> f) const {
00300 for (ParameterNode *node_ptr = tree_algo::begin_node(&m_param_tree);
00301 node_ptr != tree_algo::end_node(&m_param_tree);
00302 node_ptr = tree_algo::next_node(node_ptr))
00303 {
00304 f(node_ptr->term_ref, node_ptr->value);
00305 }
00306 }
00307
00314 inline BasicEvent& operator+=(const BasicEvent& e) {
00315 ParameterNode *new_param_ptr;
00316 for (ParameterNode *node_ptr = tree_algo::begin_node(&e.m_param_tree);
00317 node_ptr != tree_algo::end_node(&e.m_param_tree);
00318 node_ptr = tree_algo::next_node(node_ptr))
00319 {
00320 new_param_ptr = createParameter(node_ptr->term_ref, node_ptr->value);
00321 tree_algo::insert_equal_upper_bound(&m_param_tree,
00322 new_param_ptr, m_item_compare);
00323 }
00324 return *this;
00325 }
00326
00333 inline void copyValues(const BasicEvent& e, const Vocabulary::TermRef& term_ref)
00334 {
00335 std::pair<ParameterNode*, ParameterNode*> range =
00336 tree_algo::equal_range(&e.m_param_tree, term_ref, e.m_key_compare);
00337 ParameterNode *new_param_ptr;
00338 while (range.first != range.second) {
00339 new_param_ptr = createParameter(range.first->term_ref, range.first->value);
00340 tree_algo::insert_equal_upper_bound(&m_param_tree,
00341 new_param_ptr, m_item_compare);
00342 range.first = tree_algo::next_node(range.first);
00343 }
00344 }
00345
00353 inline const ParameterValue *getPointer(const Vocabulary::TermRef& term_ref) const {
00354 const ParameterNode *node_ptr = tree_algo::find(&m_param_tree, term_ref, m_key_compare);
00355 return (node_ptr==&m_param_tree ? NULL : &(node_ptr->value));
00356 }
00357
00364 inline bool isDefined(const Vocabulary::TermRef& term_ref) const {
00365 return (tree_algo::find(&m_param_tree, term_ref, m_key_compare) != &m_param_tree);
00366 }
00367
00374 inline const boost::int32_t& getInt(const Vocabulary::TermRef& term_ref) const {
00375 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<boost::int32_t>(getPointer(term_ref)));
00376 return boost::get<const boost::int32_t&>(*getPointer(term_ref));
00377 }
00378
00385 inline const boost::uint32_t& getUInt(const Vocabulary::TermRef& term_ref) const {
00386 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<boost::uint32_t>(getPointer(term_ref)));
00387 return boost::get<const boost::uint32_t&>(*getPointer(term_ref));
00388 }
00389
00396 inline const boost::int64_t& getBigInt(const Vocabulary::TermRef& term_ref) const {
00397 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<boost::int64_t>(getPointer(term_ref)));
00398 return boost::get<const boost::int64_t&>(*getPointer(term_ref));
00399 }
00400
00407 inline const boost::uint64_t& getUBigInt(const Vocabulary::TermRef& term_ref) const {
00408 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<boost::uint64_t>(getPointer(term_ref)));
00409 return boost::get<const boost::uint64_t&>(*getPointer(term_ref));
00410 }
00411
00418 inline const float& getFloat(const Vocabulary::TermRef& term_ref) const {
00419 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<float>(getPointer(term_ref)));
00420 return boost::get<const float&>(*getPointer(term_ref));
00421 }
00422
00429 inline const double& getDouble(const Vocabulary::TermRef& term_ref) const {
00430 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<double>(getPointer(term_ref)));
00431 return boost::get<const double&>(*getPointer(term_ref));
00432 }
00433
00440 inline const long double& getLongDouble(const Vocabulary::TermRef& term_ref) const {
00441 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<long double>(getPointer(term_ref)));
00442 return boost::get<const long double&>(*getPointer(term_ref));
00443 }
00444
00451 inline const PionDateTime& getDateTime(const Vocabulary::TermRef& term_ref) const {
00452 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<const PionDateTime&>(getPointer(term_ref)));
00453 return boost::get<const PionDateTime&>(*getPointer(term_ref));
00454 }
00455
00462 inline const CharType *getString(const Vocabulary::TermRef& term_ref) const {
00463 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<const BlobType&>(getPointer(term_ref)));
00464 return boost::get<const BlobType&>(*getPointer(term_ref)).get();
00465 }
00466
00473 inline const BlobType& getBlob(const Vocabulary::TermRef& term_ref) const {
00474 PION_ASSERT(getPointer(term_ref)!=NULL && boost::get<const BlobType&>(getPointer(term_ref)));
00475 return boost::get<const BlobType&>(*getPointer(term_ref));
00476 }
00477
00486 template <typename T>
00487 inline bool getInt(const Vocabulary::TermRef& term_ref, T& v) const {
00488 const ParameterValue *param_ptr = getPointer(term_ref);
00489 if (param_ptr) {
00490 v = boost::get<const boost::int32_t&>(*param_ptr);
00491 return true;
00492 }
00493 return false;
00494 }
00495
00504 template <typename T>
00505 inline bool getUInt(const Vocabulary::TermRef& term_ref, T& v) const {
00506 const ParameterValue *param_ptr = getPointer(term_ref);
00507 if (param_ptr) {
00508 v = boost::get<const boost::uint32_t&>(*param_ptr);
00509 return true;
00510 }
00511 return false;
00512 }
00513
00522 template <typename T>
00523 inline bool getBigInt(const Vocabulary::TermRef& term_ref, T& v) const {
00524 const ParameterValue *param_ptr = getPointer(term_ref);
00525 if (param_ptr) {
00526 v = boost::get<const boost::int64_t&>(*param_ptr);
00527 return true;
00528 }
00529 return false;
00530 }
00531
00540 template <typename T>
00541 inline bool getUBigInt(const Vocabulary::TermRef& term_ref, T& v) const {
00542 const ParameterValue *param_ptr = getPointer(term_ref);
00543 if (param_ptr) {
00544 v = boost::get<const boost::uint64_t&>(*param_ptr);
00545 return true;
00546 }
00547 return false;
00548 }
00549
00558 template <typename T>
00559 inline bool getFloat(const Vocabulary::TermRef& term_ref, T& v) const {
00560 const ParameterValue *param_ptr = getPointer(term_ref);
00561 if (param_ptr) {
00562 v = boost::get<const float&>(*param_ptr);
00563 return true;
00564 }
00565 return false;
00566 }
00567
00576 template <typename T>
00577 inline bool getDouble(const Vocabulary::TermRef& term_ref, T& v) const {
00578 const ParameterValue *param_ptr = getPointer(term_ref);
00579 if (param_ptr) {
00580 v = boost::get<const double&>(*param_ptr);
00581 return true;
00582 }
00583 return false;
00584 }
00585
00594 template <typename T>
00595 inline bool getLongDouble(const Vocabulary::TermRef& term_ref, T& v) const {
00596 const ParameterValue *param_ptr = getPointer(term_ref);
00597 if (param_ptr) {
00598 v = boost::get<const long double&>(*param_ptr);
00599 return true;
00600 }
00601 return false;
00602 }
00603
00612 template <typename T>
00613 inline bool getDateTime(const Vocabulary::TermRef& term_ref, T& v) const {
00614 const ParameterValue *param_ptr = getPointer(term_ref);
00615 if (param_ptr) {
00616 v = boost::get<const PionDateTime&>(*param_ptr);
00617 return true;
00618 }
00619 return false;
00620 }
00621
00630 template <typename T>
00631 inline bool getBlob(const Vocabulary::TermRef& term_ref, T& v) const {
00632 const ParameterValue *param_ptr = getPointer(term_ref);
00633 if (param_ptr) {
00634 v = boost::get<const BlobType&>(*param_ptr);
00635 return true;
00636 }
00637 return false;
00638 }
00639
00648 inline bool getBlob(const Vocabulary::TermRef& term_ref, std::string& str) const {
00649 const ParameterValue *param_ptr = getPointer(term_ref);
00650 if (param_ptr) {
00651 str = boost::get<const BlobType&>(*param_ptr).get();
00652 return true;
00653 }
00654 return false;
00655 }
00656
00665 template <typename T>
00666 inline bool getString(const Vocabulary::TermRef& term_ref, T& v) const {
00667 return getBlob(term_ref, v);
00668 }
00669
00678 inline bool getString(const Vocabulary::TermRef& term_ref, std::string& str) const {
00679 return getBlob(term_ref, str);
00680 }
00681
00688 template <typename T>
00689 inline void setInt(const Vocabulary::TermRef& term_ref, T value) {
00690 insert(term_ref, boost::int32_t(value));
00691 }
00692
00699 inline void setInt(const Vocabulary::TermRef& term_ref, const std::string& value) {
00700 insert(term_ref, boost::lexical_cast<boost::int32_t>(value));
00701 }
00702
00709 template <typename T>
00710 inline void setUInt(const Vocabulary::TermRef& term_ref, T value) {
00711 insert(term_ref, boost::uint32_t(value));
00712 }
00713
00720 inline void setUInt(const Vocabulary::TermRef& term_ref, const std::string& value) {
00721 insert(term_ref, boost::lexical_cast<boost::uint32_t>(value));
00722 }
00723
00730 template <typename T>
00731 inline void setBigInt(const Vocabulary::TermRef& term_ref, T value) {
00732 insert(term_ref, boost::int64_t(value));
00733 }
00734
00741 inline void setBigInt(const Vocabulary::TermRef& term_ref, const std::string& value) {
00742 insert(term_ref, boost::lexical_cast<boost::int64_t>(value));
00743 }
00744
00751 template <typename T>
00752 inline void setUBigInt(const Vocabulary::TermRef& term_ref, T value) {
00753 insert(term_ref, boost::uint64_t(value));
00754 }
00755
00762 inline void setUBigInt(const Vocabulary::TermRef& term_ref, const std::string& value) {
00763 insert(term_ref, boost::lexical_cast<boost::uint64_t>(value));
00764 }
00765
00772 inline void setFloat(const Vocabulary::TermRef& term_ref, const float value) {
00773 insert(term_ref, value);
00774 }
00775
00782 inline void setFloat(const Vocabulary::TermRef& term_ref, const std::string& value) {
00783 insert(term_ref, boost::lexical_cast<float>(value));
00784 }
00785
00792 inline void setDouble(const Vocabulary::TermRef& term_ref, const double value) {
00793 insert(term_ref, value);
00794 }
00795
00802 inline void setDouble(const Vocabulary::TermRef& term_ref, const std::string& value) {
00803 insert(term_ref, boost::lexical_cast<double>(value));
00804 }
00805
00812 inline void setLongDouble(const Vocabulary::TermRef& term_ref, const long double value) {
00813 insert(term_ref, value);
00814 }
00815
00822 inline void setLongDouble(const Vocabulary::TermRef& term_ref, const std::string& value) {
00823 insert(term_ref, boost::lexical_cast<long double>(value));
00824 }
00825
00832 inline void setDateTime(const Vocabulary::TermRef& term_ref, const PionDateTime& value) {
00833 insert(term_ref, value);
00834 }
00835
00843 inline void setBlob(const Vocabulary::TermRef& term_ref,
00844 const CharType *value, std::size_t len)
00845 {
00846 insert(term_ref, make_blob(value, len));
00847 }
00848
00855 inline void setBlob(const Vocabulary::TermRef& term_ref, const CharType *value) {
00856 insert(term_ref, make_blob(value, strlen(value)));
00857 }
00858
00865 inline void setBlob(const Vocabulary::TermRef& term_ref, const std::string& value) {
00866 insert(term_ref, make_blob(value));
00867 }
00868
00875 inline void setBlob(const Vocabulary::TermRef& term_ref, const BlobType& value) {
00876 insert(term_ref, value);
00877 }
00878
00886 inline void setString(const Vocabulary::TermRef& term_ref,
00887 const CharType *value, std::size_t len)
00888 {
00889 setBlob(term_ref, value, len);
00890 }
00891
00898 inline void setString(const Vocabulary::TermRef& term_ref, const CharType *value) {
00899 setBlob(term_ref, value);
00900 }
00901
00908 inline void setString(const Vocabulary::TermRef& term_ref, const std::string& value) {
00909 setBlob(term_ref, value);
00910 }
00911
00918 inline void setString(const Vocabulary::TermRef& term_ref, const BlobType& value) {
00919 setBlob(term_ref, value);
00920 }
00921
00929 inline void set(const Vocabulary::Term& t, const std::string& value)
00930 {
00931 switch (t.term_type) {
00932 case Vocabulary::TYPE_NULL:
00933 case Vocabulary::TYPE_OBJECT:
00934
00935 throw TermTypeNotSerializableException();
00936 break;
00937 case Vocabulary::TYPE_INT8:
00938 case Vocabulary::TYPE_INT16:
00939 case Vocabulary::TYPE_INT32:
00940 setInt(t.term_ref, value);
00941 break;
00942 case Vocabulary::TYPE_UINT8:
00943 case Vocabulary::TYPE_UINT16:
00944 case Vocabulary::TYPE_UINT32:
00945 setUInt(t.term_ref, value);
00946 break;
00947 case Vocabulary::TYPE_INT64:
00948 setBigInt(t.term_ref, value);
00949 break;
00950 case Vocabulary::TYPE_UINT64:
00951 setUBigInt(t.term_ref, value);
00952 break;
00953 case Vocabulary::TYPE_FLOAT:
00954 setFloat(t.term_ref, value);
00955 break;
00956 case Vocabulary::TYPE_DOUBLE:
00957 setDouble(t.term_ref, value);
00958 break;
00959 case Vocabulary::TYPE_LONG_DOUBLE:
00960 setLongDouble(t.term_ref, value);
00961 break;
00962 case Vocabulary::TYPE_DATE_TIME:
00963 case Vocabulary::TYPE_DATE:
00964 case Vocabulary::TYPE_TIME:
00965 {
00966 pion::PionTimeFacet f(t.term_format);
00967 const pion::PionDateTime pdt(f.fromString(value));
00968 setDateTime(t.term_ref, pdt);
00969 break;
00970 }
00971 case Vocabulary::TYPE_SHORT_STRING:
00972 case Vocabulary::TYPE_STRING:
00973 case Vocabulary::TYPE_LONG_STRING:
00974 case Vocabulary::TYPE_CHAR:
00975 case Vocabulary::TYPE_BLOB:
00976 case Vocabulary::TYPE_ZBLOB:
00977 setString(t.term_ref, value);
00978 break;
00979 }
00980 }
00981
00989 static inline bool write(std::ostream& str, const ParameterValue& value,
00990 const Vocabulary::Term& t)
00991 {
00992 switch (t.term_type) {
00993 case Vocabulary::TYPE_NULL:
00994 case Vocabulary::TYPE_OBJECT:
00995
00996 throw TermTypeNotSerializableException();
00997 break;
00998 case Vocabulary::TYPE_INT8:
00999 case Vocabulary::TYPE_INT16:
01000 case Vocabulary::TYPE_INT32:
01001 str << boost::get<const boost::int32_t&>(value);
01002 break;
01003 case Vocabulary::TYPE_UINT8:
01004 case Vocabulary::TYPE_UINT16:
01005 case Vocabulary::TYPE_UINT32:
01006 str << boost::get<const boost::uint32_t&>(value);
01007 break;
01008 case Vocabulary::TYPE_INT64:
01009 str << boost::get<const boost::int64_t&>(value);
01010 break;
01011 case Vocabulary::TYPE_UINT64:
01012 str << boost::get<const boost::uint64_t&>(value);
01013 break;
01014 case Vocabulary::TYPE_FLOAT:
01015 str << boost::get<const float&>(value);
01016 break;
01017 case Vocabulary::TYPE_DOUBLE:
01018 str << boost::get<const double&>(value);
01019 break;
01020 case Vocabulary::TYPE_LONG_DOUBLE:
01021 str << boost::get<const long double&>(value);
01022 break;
01023 case Vocabulary::TYPE_SHORT_STRING:
01024 case Vocabulary::TYPE_STRING:
01025 case Vocabulary::TYPE_LONG_STRING:
01026 case Vocabulary::TYPE_CHAR:
01027 case Vocabulary::TYPE_BLOB:
01028 case Vocabulary::TYPE_ZBLOB:
01029 str << boost::get<const BlobType&>(value).get();
01030 break;
01031 case Vocabulary::TYPE_DATE_TIME:
01032 case Vocabulary::TYPE_DATE:
01033 case Vocabulary::TYPE_TIME:
01034 {
01035 pion::PionTimeFacet f(t.term_format);
01036 f.write(str, boost::get<const PionDateTime&>(value));
01037 break;
01038 }
01039 }
01040 }
01041
01049 static inline std::string& write(std::string& str, const ParameterValue& value,
01050 const Vocabulary::Term& t)
01051 {
01052 switch (t.term_type) {
01053 case Vocabulary::TYPE_NULL:
01054 case Vocabulary::TYPE_OBJECT:
01055
01056 throw TermTypeNotSerializableException();
01057 break;
01058 case Vocabulary::TYPE_INT8:
01059 case Vocabulary::TYPE_INT16:
01060 case Vocabulary::TYPE_INT32:
01061 str = boost::lexical_cast<std::string>( boost::get<const boost::int32_t&>(value) );
01062 break;
01063 case Vocabulary::TYPE_UINT8:
01064 case Vocabulary::TYPE_UINT16:
01065 case Vocabulary::TYPE_UINT32:
01066 str = boost::lexical_cast<std::string>( boost::get<const boost::uint32_t&>(value) );
01067 break;
01068 case Vocabulary::TYPE_INT64:
01069 str = boost::lexical_cast<std::string>( boost::get<const boost::int64_t&>(value) );
01070 break;
01071 case Vocabulary::TYPE_UINT64:
01072 str = boost::lexical_cast<std::string>( boost::get<const boost::uint64_t&>(value) );
01073 break;
01074 case Vocabulary::TYPE_FLOAT:
01075 str = boost::lexical_cast<std::string>( boost::get<const float&>(value) );
01076 break;
01077 case Vocabulary::TYPE_DOUBLE:
01078 str = boost::lexical_cast<std::string>( boost::get<const double&>(value) );
01079 break;
01080 case Vocabulary::TYPE_LONG_DOUBLE:
01081 str = boost::lexical_cast<std::string>( boost::get<const long double&>(value) );
01082 break;
01083 case Vocabulary::TYPE_SHORT_STRING:
01084 case Vocabulary::TYPE_STRING:
01085 case Vocabulary::TYPE_LONG_STRING:
01086 case Vocabulary::TYPE_CHAR:
01087 case Vocabulary::TYPE_BLOB:
01088 case Vocabulary::TYPE_ZBLOB:
01089 str = boost::get<const BlobType&>(value).get();
01090 break;
01091 case Vocabulary::TYPE_DATE_TIME:
01092 case Vocabulary::TYPE_DATE:
01093 case Vocabulary::TYPE_TIME:
01094 {
01095 pion::PionTimeFacet f(t.term_format);
01096 str = f.toString( boost::get<const PionDateTime&>(value) );
01097 break;
01098 }
01099 }
01100 return str;
01101 }
01102
01104 inline BlobParams make_blob(const std::string& str) const {
01105 return BlobParams(*m_alloc_ptr, str.c_str(), str.size());
01106 }
01107
01109 inline BlobParams make_blob(const CharType *ptr, const std::size_t len) const {
01110 return BlobParams(*m_alloc_ptr, ptr, len);
01111 }
01112
01114 inline BlobParams make_blob(const CharType *ptr) const {
01115 return BlobParams(*m_alloc_ptr, ptr, strlen(ptr));
01116 }
01117
01119 inline boost::uint32_t getReferences(void) const { return m_references; }
01120
01121
01122 protected:
01123
01125 friend class EventPtr;
01126
01128 friend class EventFactory;
01129
01131 inline void addReference(void) { ++m_references; }
01132
01134 inline boost::uint32_t removeReference(void) { return --m_references; }
01135
01137 inline AllocType *getAllocator(void) { return m_alloc_ptr; }
01138
01145 template <typename T>
01146 inline void insert(const Vocabulary::TermRef& term_ref, const T& value) {
01147 PION_ASSERT(term_ref != Vocabulary::UNDEFINED_TERM_REF);
01148 ParameterNode *new_param_ptr = createParameter(term_ref, value);
01149 tree_algo::insert_equal_upper_bound(&m_param_tree,
01150 new_param_ptr, m_item_compare);
01151 }
01152
01161 template <typename T>
01162 inline ParameterNode *createParameter(const Vocabulary::TermRef& term_ref, const T& value) {
01163 void *mem_ptr = m_alloc_ptr->malloc(sizeof(ParameterNode));
01164 return new (mem_ptr) ParameterNode(term_ref, value);
01165 }
01166
01172 inline void destroyParameter(ParameterNode *param_ptr) {
01173 param_ptr->~ParameterNode();
01174 m_alloc_ptr->free(param_ptr, sizeof(ParameterNode));
01175 }
01176
01177
01179 struct ParameterNodeCompare {
01181 inline bool operator()(const ParameterNode *a, const ParameterNode *b) const {
01182 return (a->term_ref < b->term_ref);
01183 }
01184 };
01185
01187 struct ParameterKeyCompare {
01189 inline bool operator()(const ParameterNode *a, const Vocabulary::TermRef& b) const {
01190 return (a->term_ref < b);
01191 }
01193 inline bool operator()(const Vocabulary::TermRef& a, const ParameterNode *b) const {
01194 return (a < b->term_ref);
01195 }
01196 };
01197
01199 struct ParameterNodeTraits {
01200 typedef ParameterNode node;
01201 typedef ParameterNode * node_ptr;
01202 typedef const ParameterNode * const_node_ptr;
01203 typedef boost::uint8_t color;
01204 static node_ptr get_parent(const_node_ptr n) { return n->m_parent_ptr; }
01205 static void set_parent(node_ptr n, node_ptr parent){ n->m_parent_ptr = parent; }
01206 static node_ptr get_left(const_node_ptr n) { return n->m_left_ptr; }
01207 static void set_left(node_ptr n, node_ptr left) { n->m_left_ptr = left; }
01208 static node_ptr get_right(const_node_ptr n) { return n->m_right_ptr; }
01209 static void set_right(node_ptr n, node_ptr right) { n->m_right_ptr = right; }
01210 static color get_color(const_node_ptr n) { return n->m_tree_color; }
01211 static void set_color(node_ptr n, color c) { n->m_tree_color = c; }
01212 static color black() { return color(0); }
01213 static color red() { return color(1); }
01214 };
01215
01217 typedef boost::intrusive::rbtree_algorithms<ParameterNodeTraits> tree_algo;
01218
01219
01220 private:
01221
01223 const EventType m_event_type;
01224
01226 ParameterNode m_param_tree;
01227
01229 ParameterNodeCompare m_item_compare;
01230
01232 ParameterKeyCompare m_key_compare;
01233
01235 AllocType * const m_alloc_ptr;
01236
01238 boost::detail::atomic_count m_references;
01239 };
01240
01241
01242 #ifdef PION_EVENT_USE_POOL_ALLOCATORS
01243
01245 typedef PionPoolAllocator<16, 256> EventAllocator;
01246
01247 #else
01248
01250 struct DummyEventAllocator {
01258 inline void *malloc(std::size_t n) { return ::malloc(n); }
01259
01266 inline void free(void *ptr, std::size_t n) { ::free(ptr); }
01267 };
01268
01270 typedef DummyEventAllocator EventAllocator;
01271
01272 #endif
01273
01274
01276 typedef BasicEvent<char, EventAllocator> Event;
01277
01278
01282 class EventPtr {
01283 public:
01284
01286 ~EventPtr() { reset(); }
01287
01289 EventPtr(void) : m_event_ptr(NULL) {}
01290
01292 EventPtr(const EventPtr& ptr)
01293 : m_event_ptr(ptr.m_event_ptr)
01294 {
01295 if (m_event_ptr != NULL)
01296 m_event_ptr->addReference();
01297 }
01298
01300 inline EventPtr& operator=(const EventPtr& ptr) { reset(ptr); return *this; }
01301
01303 inline Event& operator*() const { return *m_event_ptr; }
01304
01306 inline Event* operator->() const { return m_event_ptr; }
01307
01309 inline Event *get(void) const { return m_event_ptr; }
01310
01312 inline bool is_safe(void) const {
01313 return (m_event_ptr != NULL && m_event_ptr->getReferences()==1);
01314 }
01315
01317 inline void reset(void) {
01318 if (m_event_ptr != NULL) {
01319 if (m_event_ptr->removeReference() == 0) {
01320 EventAllocator *alloc_ptr = m_event_ptr->getAllocator();
01321 m_event_ptr->~Event();
01322 alloc_ptr->free(m_event_ptr, sizeof(Event));
01323 }
01324 m_event_ptr = NULL;
01325 }
01326 }
01327
01329 inline void reset(const EventPtr& ptr) {
01330 reset();
01331 m_event_ptr = ptr.m_event_ptr;
01332 if (m_event_ptr != NULL)
01333 m_event_ptr->addReference();
01334 }
01335
01337 inline void swap(EventPtr& ptr) {
01338 Event *tmp_event_ptr(ptr.m_event_ptr);
01339 ptr.m_event_ptr = m_event_ptr;
01340 m_event_ptr = tmp_event_ptr;
01341 }
01342
01343
01344 protected:
01345
01347 friend class EventFactory;
01348
01350 EventPtr(Event *event_ptr)
01351 : m_event_ptr(event_ptr)
01352 {
01353 if (m_event_ptr != NULL)
01354 m_event_ptr->addReference();
01355 }
01356
01357
01358 private:
01359
01361 Event * m_event_ptr;
01362 };
01363
01364
01369 class PION_PLATFORM_API EventFactory :
01370 private boost::noncopyable
01371 {
01372 public:
01373
01375 ~EventFactory() {}
01376
01378 EventFactory(void)
01379 : m_event_alloc(EventAllocatorFactory::getAllocator())
01380 {}
01381
01383 explicit EventFactory(EventAllocator& alloc)
01384 : m_event_alloc(alloc)
01385 {}
01386
01388 explicit EventFactory(Event& e)
01389 : m_event_alloc(*e.getAllocator())
01390 {}
01391
01400 inline EventPtr create(const Event::EventType t) {
01401 void *mem_ptr = m_event_alloc.malloc(sizeof(Event));
01402 return EventPtr(new (mem_ptr) Event(t, &m_event_alloc));
01403 }
01404
01411 inline void create(EventPtr& ptr, const Event::EventType t) {
01412 if (ptr.is_safe() && ptr->getType() == t)
01413 ptr->clear();
01414 else
01415 ptr = create(t);
01416 }
01417
01419 inline EventAllocator& getAllocator(void) { return m_event_alloc; }
01420
01422 inline Event::BlobParams make_blob(const std::string& str) const {
01423 return Event::BlobParams(m_event_alloc, str.c_str(), str.size());
01424 }
01425
01427 inline Event::BlobParams make_blob(const char *ptr, const std::size_t len) const {
01428 return Event::BlobParams(m_event_alloc, ptr, len);
01429 }
01430
01432 inline Event::BlobParams make_blob(const char *ptr) const {
01433 return Event::BlobParams(m_event_alloc, ptr, strlen(ptr));
01434 }
01435
01436
01437 private:
01438
01442 class EventAllocatorFactory {
01443 public:
01444
01446 ~EventAllocatorFactory() {
01447 #ifdef PION_EVENT_USE_POOL_ALLOCATORS
01448
01449 boost::unique_lock<boost::mutex> alloc_lock(m_alloc_mutex);
01450
01451 for (std::list<EventAllocator*>::iterator i = m_active_allocs.begin();
01452 i != m_active_allocs.end(); ++i)
01453 {
01454 delete *i;
01455 }
01456 for (std::list<EventAllocator*>::iterator i = m_inactive_allocs.begin();
01457 i != m_inactive_allocs.end(); ++i)
01458 {
01459 delete *i;
01460 }
01461
01462
01463
01464 m_thread_alloc.release();
01465 #endif
01466 }
01467
01473 inline static EventAllocator& getAllocator(void) {
01474 boost::call_once(EventAllocatorFactory::createInstance, m_instance_flag);
01475 EventAllocator *alloc_ptr;
01476 #ifdef PION_EVENT_USE_POOL_ALLOCATORS
01477 alloc_ptr = m_instance_ptr->m_thread_alloc.get();
01478 if (alloc_ptr == NULL) {
01479
01480 boost::unique_lock<boost::mutex> alloc_lock(m_instance_ptr->m_alloc_mutex);
01481 if (m_instance_ptr->m_inactive_allocs.empty()) {
01482
01483 alloc_ptr = new EventAllocator();
01484 } else {
01485
01486 alloc_ptr = m_instance_ptr->m_inactive_allocs.front();
01487 m_instance_ptr->m_inactive_allocs.pop_front();
01488
01489 alloc_ptr->release_memory();
01490 }
01491
01492 m_instance_ptr->m_active_allocs.push_back(alloc_ptr);
01493
01494 m_instance_ptr->m_thread_alloc.reset(alloc_ptr);
01495 }
01496 #else
01497 alloc_ptr = & m_instance_ptr->m_single_alloc;
01498 #endif
01499 return *alloc_ptr;
01500 }
01501
01502
01503 private:
01504
01506 EventAllocatorFactory(void)
01507 #ifdef PION_EVENT_USE_POOL_ALLOCATORS
01508 : m_thread_alloc(&EventAllocatorFactory::releaseAllocator)
01509 #endif
01510 {}
01511
01513 static void createInstance(void);
01514
01516 static void releaseAllocator(EventAllocator *ptr) {
01517 #ifdef PION_EVENT_USE_POOL_ALLOCATORS
01518
01519 boost::unique_lock<boost::mutex> alloc_lock(m_instance_ptr->m_alloc_mutex);
01520
01521 for (std::list<EventAllocator*>::iterator i = m_instance_ptr->m_active_allocs.begin();
01522 i != m_instance_ptr->m_active_allocs.end(); ++i)
01523 {
01524 if (ptr == *i) {
01525 m_instance_ptr->m_active_allocs.erase(i);
01526 break;
01527 }
01528 }
01529
01530 ptr->release_memory();
01531
01532 m_instance_ptr->m_inactive_allocs.push_back(ptr);
01533 #endif
01534 }
01535
01536
01537 #ifdef PION_EVENT_USE_POOL_ALLOCATORS
01539 boost::thread_specific_ptr<EventAllocator> m_thread_alloc;
01540
01542 std::list<EventAllocator*> m_active_allocs;
01543
01545 std::list<EventAllocator*> m_inactive_allocs;
01546
01548 boost::mutex m_alloc_mutex;
01549 #else
01551 EventAllocator m_single_alloc;
01552 #endif
01553
01555 static EventAllocatorFactory * m_instance_ptr;
01556
01558 static boost::once_flag m_instance_flag;
01559 };
01560
01561
01563 EventAllocator & m_event_alloc;
01564 };
01565
01566
01574 typedef std::vector<EventPtr> EventContainer;
01575
01576
01577 }
01578 }
01579
01580 #endif