Changeset 599

Show
Ignore:
Timestamp:
07/21/08 14:16:29 (4 months ago)
Author:
weyrick
Message:

support numeric keys, next

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/rphp/runtime/include/pHash.h

    r593 r599  
    2020#define RPHP_PHASH_H_ 
    2121 
     22#include <boost/variant.hpp> 
    2223#include <boost/multi_index_container.hpp> 
    2324#include <boost/multi_index/hashed_index.hpp> 
     
    2829#include "pVar.h" 
    2930 
    30 // hash function for use with rphp::pUString 
    31 U_NAMESPACE_BEGIN 
    32     std::size_t hash_value(rphp::pUString const& s); 
    33 U_NAMESPACE_END 
    34  
    3531using boost::multi_index_container; 
    3632using namespace boost::multi_index; 
    3733 
     34// custom key type 
     35namespace rphp { 
     36    typedef boost::variant< pInt, pUString > hKeyVar; 
     37    typedef enum { hKeyInt, hKeyStr  } hKeyType; 
     38} 
     39 
     40// customer key hasher 
     41namespace boost { 
     42    std::size_t hash_value(rphp::hKeyVar const& k); 
     43} 
     44 
    3845namespace rphp { 
    3946 
    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> { 
    4549 
    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 
    4778    struct h_container { 
    4879 
    49         pVarP data; 
    50         const pUString key; 
    51         // TODO: php has support for numeric keys 
     80        pVarP pData; 
     81        hKeyVar key; 
    5282 
    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) { } 
    5486 
    5587    }; 
     
    6294        // index definitions: hash and sequence 
    6395        indexed_by< 
    64             hashed_unique< member<h_container, const pUString, &h_container::key> >, 
     96            hashed_unique< member<h_container, hKeyVar, &h_container::key> >, 
    6597            sequenced<> 
    6698        > 
     
    77109        private: 
    78110            stableHash hashData; 
     111            pInt maxIntKey; 
    79112 
    80113        public: 
     
    84117 
    85118            // construct/destroy/copy 
    86             pHash() { std::cout << "creating fresh pHash" << std::endl; } 
     119            pHash() : maxIntKey(0) { std::cout << "creating fresh pHash" << std::endl; } 
    87120 
    88             pHash(pHash const& p)
     121            pHash(pHash const& p) : maxIntKey(p.maxIntKey)
    89122                std::cout << "pHash copy construct" << std::endl; 
    90123                hashData = p.hashData; 
     
    95128            // modifiers 
    96129            void insert(const pUString &key, pVarP data); 
     130            void insert(const pInt &key, pVarP data); 
     131            void insertNext(pVarP data); 
    97132 
    98133            // size 
     
    108143                    return pVarP(); 
    109144                else 
    110                     return (*k).data; 
     145                    return (*k).pData; 
    111146            } 
    112147 
  • trunk/rphp/runtime/pHash.cpp

    r593 r599  
    2020#include "pHash.h" 
    2121 
    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 
     23namespace boost { 
     24    std::size_t hash_value(rphp::hKeyVar const& k) { 
     25        return boost::apply_visitor(rphp::hKeyHasher(), k); 
    2626    } 
    27 U_NAMESPACE_END 
     27
    2828 
    2929namespace rphp { 
    30  
     30     
    3131    void pHash::insert(const pUString &key, pVarP data) { 
    32  
     32        // TODO check numeric string, set maxIntKey accordingly 
    3333        hashData.insert(h_container(key, data)); 
    34  
    3534    } 
    3635 
     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     
    3746    void pHash::varDump() { 
    3847 
     
    4251        seq_index& ot = get<1>(hashData); 
    4352 
     53        hKeyType kType; 
     54         
    4455        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; 
    4661        } 
    4762 
  • trunk/rphp/runtime/test/phashTestCase.cpp

    r593 r599  
    2727    CPPUNIT_ASSERT( int2.get() == 0 ); 
    2828 
     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     
    2937    h.varDump(); 
    3038