Changeset 599
- Timestamp:
- 07/21/08 14:16:29 (4 months ago)
- Files:
-
- trunk/rphp/runtime/include/pHash.h (modified) (7 diffs)
- trunk/rphp/runtime/pHash.cpp (modified) (2 diffs)
- trunk/rphp/runtime/test/phashTestCase.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/rphp/runtime/include/pHash.h
r593 r599 20 20 #define RPHP_PHASH_H_ 21 21 22 #include <boost/variant.hpp> 22 23 #include <boost/multi_index_container.hpp> 23 24 #include <boost/multi_index/hashed_index.hpp> … … 28 29 #include "pVar.h" 29 30 30 // hash function for use with rphp::pUString31 U_NAMESPACE_BEGIN32 std::size_t hash_value(rphp::pUString const& s);33 U_NAMESPACE_END34 35 31 using boost::multi_index_container; 36 32 using namespace boost::multi_index; 37 33 34 // custom key type 35 namespace rphp { 36 typedef boost::variant< pInt, pUString > hKeyVar; 37 typedef enum { hKeyInt, hKeyStr } hKeyType; 38 } 39 40 // customer key hasher 41 namespace boost { 42 std::size_t hash_value(rphp::hKeyVar const& k); 43 } 44 38 45 namespace rphp { 39 46 40 /* 41 * defines an interface to a hash table class which implements php style 42 * hash table/array semantics 43 * 44 */ 47 // a visitor for hashing phash keys 48 class hKeyHasher : public boost::static_visitor<std::size_t> { 45 49 46 // container stored in stableHash 50 public: 51 52 std::size_t operator()(const pInt &k) const { 53 return static_cast<std::size_t>(k); 54 } 55 56 std::size_t operator()(const pUString &k) const { 57 return static_cast<std::size_t>(k.hashCode()); 58 } 59 60 }; 61 62 // a visitor for determining phash key type 63 class hKeyGetType : public boost::static_visitor<hKeyType> { 64 65 public: 66 67 hKeyType operator()(const pInt &k) const { 68 return hKeyInt; 69 } 70 71 hKeyType operator()(const pUString &k) const { 72 return hKeyStr; 73 } 74 75 }; 76 77 // define the container stored in stableHash 47 78 struct h_container { 48 79 49 pVarP data; 50 const pUString key; 51 // TODO: php has support for numeric keys 80 pVarP pData; 81 hKeyVar key; 52 82 53 h_container(const pUString k, pVarP d) : data(d), key(k) { } 83 h_container(const pUString k, pVarP d) : pData(d), key(k) { } 84 85 h_container(const pInt k, pVarP d) : pData(d), key(k) { } 54 86 55 87 }; … … 62 94 // index definitions: hash and sequence 63 95 indexed_by< 64 hashed_unique< member<h_container, const pUString, &h_container::key> >,96 hashed_unique< member<h_container, hKeyVar, &h_container::key> >, 65 97 sequenced<> 66 98 > … … 77 109 private: 78 110 stableHash hashData; 111 pInt maxIntKey; 79 112 80 113 public: … … 84 117 85 118 // construct/destroy/copy 86 pHash() { std::cout << "creating fresh pHash" << std::endl; }119 pHash() : maxIntKey(0) { std::cout << "creating fresh pHash" << std::endl; } 87 120 88 pHash(pHash const& p) {121 pHash(pHash const& p) : maxIntKey(p.maxIntKey) { 89 122 std::cout << "pHash copy construct" << std::endl; 90 123 hashData = p.hashData; … … 95 128 // modifiers 96 129 void insert(const pUString &key, pVarP data); 130 void insert(const pInt &key, pVarP data); 131 void insertNext(pVarP data); 97 132 98 133 // size … … 108 143 return pVarP(); 109 144 else 110 return (*k). data;145 return (*k).pData; 111 146 } 112 147 trunk/rphp/runtime/pHash.cpp
r593 r599 20 20 #include "pHash.h" 21 21 22 U_NAMESPACE_BEGIN 23 // this is used by the multi_index for hashing unicode strings 24 std::size_t hash_value(rphp:: pUString const& s) {25 return static_cast<std::size_t>(s.hashCode());22 23 namespace boost { 24 std::size_t hash_value(rphp::hKeyVar const& k) { 25 return boost::apply_visitor(rphp::hKeyHasher(), k); 26 26 } 27 U_NAMESPACE_END 27 } 28 28 29 29 namespace rphp { 30 30 31 31 void pHash::insert(const pUString &key, pVarP data) { 32 32 // TODO check numeric string, set maxIntKey accordingly 33 33 hashData.insert(h_container(key, data)); 34 35 34 } 36 35 36 void pHash::insert(const pInt &key, pVarP data) { 37 if (key > maxIntKey) 38 maxIntKey = key+1; 39 hashData.insert(h_container(key, data)); 40 } 41 42 void pHash::insertNext(pVarP data) { 43 hashData.insert(h_container(maxIntKey++, data)); 44 } 45 37 46 void pHash::varDump() { 38 47 … … 42 51 seq_index& ot = get<1>(hashData); 43 52 53 hKeyType kType; 54 44 55 for (seq_index::iterator it = ot.begin(); it!=ot.end(); it++) { 45 std::cout << " ['" << (*it).key << "'] => " << *(*it).data << std::endl; 56 kType = boost::apply_visitor(rphp::hKeyGetType(), (*it).key); 57 if (kType == hKeyInt) 58 std::cout << " [" << (*it).key << "] => " << *(*it).pData << std::endl; 59 else 60 std::cout << " ['" << (*it).key << "'] => " << *(*it).pData << std::endl; 46 61 } 47 62 trunk/rphp/runtime/test/phashTestCase.cpp
r593 r599 27 27 CPPUNIT_ASSERT( int2.get() == 0 ); 28 28 29 // int key 30 rphp::pVarP str1(new rphp::pVar(rphp::pBString("int key 1"))); 31 h.insert(55, str1); 32 33 // next key 34 rphp::pVarP str2(new rphp::pVar(rphp::pBString("next key"))); 35 h.insertNext(str2); 36 29 37 h.varDump(); 30 38
