ValueMap.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _SUPPORT_VALUEMAP_H
00014 #define _SUPPORT_VALUEMAP_H
00015 
00016 #include <support/Locker.h>
00017 #include <support/IByteStream.h>
00018 #include <support/Value.h>
00019 #include <support/Vector.h>
00020 
00021 #include <support_p/ValueMapFormat.h>
00022 #include <support_p/SupportMisc.h>
00023 
00024 #if _SUPPORTS_NAMESPACE || _REQUIRES_NAMESPACE
00025 namespace std {
00026 #endif
00027     struct nothrow_t;
00028 #if _SUPPORTS_NAMESPACE || _REQUIRES_NAMESPACE
00029 }
00030 #endif
00031 
00032 #if _SUPPORTS_NAMESPACE
00033 namespace palmos {
00034 namespace support {
00035 #endif
00036 
00037 class SParcel;
00038 class BValueMap;
00039 
00040 class BValueMapPool
00041 {
00042 public:
00043     BValueMapPool();
00044     ~BValueMapPool();
00045 
00046     BValueMap* Create(size_t initSize);
00047     void Delete(BValueMap* map);
00048 
00049     int32_t Hits() const { return m_hits; }
00050     int32_t Misses() const { return m_misses; }
00051 
00052 private:
00053     SLocker m_lock;
00054     struct pool {
00055         int32_t count;
00056         BValueMap* objects;
00057 
00058         pool() : count(0), objects(NULL) { }
00059     };
00060     enum { NUM_POOLS = 3 };
00061     pool m_pools[NUM_POOLS];
00062     int32_t m_hits, m_misses;
00063 };
00064 
00065 extern BValueMapPool g_valueMapPool;
00066 
00067 class BValueMap
00068 {
00069 public:
00070             struct pair {
00071                 SValue key;
00072                 SValue value;
00073                 
00074                 inline pair() { }
00075                 inline pair(const SValue& k, const SValue& v)   :   key(k), value(v) { }
00076                 inline pair(const pair& o)                      :   key(o.key), value(o.value) { }
00077                 inline ~pair() { }
00078                 
00079                 inline pair& operator=(const pair& o) { key = o.key; value = o.value; return *this; }
00080             };
00081             
00082     static  BValueMap*      Create(size_t initSize = 1);
00083     static  BValueMap*      Create(SParcel& from, size_t avail, size_t count, ssize_t* out_size);
00084             BValueMap*      Clone() const;
00085 
00086             void            SetFirstMap(const SValue& key, const SValue& value);
00087 
00088             void            IncUsers() const;
00089             void            DecUsers() const;
00090             bool            IsShared() const;
00091     
00092             ssize_t         ArchivedSize() const;
00093             ssize_t         Archive(SParcel& into) const;
00094             ssize_t         IndexFor(   const SValue& key,
00095                                         const SValue& value = B_UNDEFINED_VALUE) const;
00096             ssize_t         IndexFor(   uint32_t type, const void* data, size_t length) const;
00097             const pair&     MapAt(size_t index) const;
00098 
00099             size_t          CountMaps() const;
00100             int32_t         Compare(const BValueMap& o) const;
00101             int32_t         LexicalCompare(const BValueMap& o) const;
00102             
00103     static  ssize_t         AddNewMap(BValueMap** This, const SValue& key, const SValue& value);
00104     static  status_t        RemoveMap(  BValueMap** This,
00105                                         const SValue& key,
00106                                         const SValue& value = B_UNDEFINED_VALUE);
00107     static  void            RemoveMapAt(BValueMap** This, size_t index);
00108     static  status_t        RenameMap(  BValueMap** This,
00109                                         const SValue& old_key,
00110                                         const SValue& new_key);
00111             
00112     static  SValue*         BeginEditMapAt(BValueMap** This, size_t index);
00113     static  void            EndEditMapAt(BValueMap** This);
00114             bool            IsEditing() const;
00115 
00116             void            Pool();
00117 
00118             void            AssertEditing() const;
00119             
00120 private:
00121     friend  class           BValueMapPool;
00122 
00123                             // These are not implemented.
00124                             BValueMap();
00125                             BValueMap(const BValueMap& o);
00126                             ~BValueMap();
00127 
00128             void            Construct(int32_t avail);
00129             void            Destroy();
00130 
00131             void            Delete();
00132             
00133     static  ssize_t         AddMapAt(BValueMap** This, size_t index, const SValue& key, const SValue& value);
00134 
00135             bool            GetIndexOf( uint32_t type, const void* data, size_t length,
00136                                         size_t* index) const;
00137             bool            GetIndexOf( const SValue& k, const SValue& v,
00138                                         size_t* index) const;
00139             ssize_t         ComputeArchivedSize() const;
00140 
00141     mutable int32_t         m_users;
00142     mutable ssize_t         m_dataSize;
00143             ssize_t         m_size;
00144             ssize_t         m_avail;
00145             int32_t         m_pad0;
00146             ssize_t         m_editIndex;
00147 
00148             // Mappings start here.
00149             pair            m_maps[1];
00150 };
00151 
00152 inline void BValueMap::IncUsers() const
00153 {
00154     AssertEditing();
00155     
00156     g_threadDirectFuncs.atomicInc32(&m_users);
00157 }
00158 
00159 inline void BValueMap::DecUsers() const
00160 {
00161     AssertEditing();
00162     
00163     if (g_threadDirectFuncs.atomicDec32(&m_users) == 1)
00164         const_cast<BValueMap*>(this)->Delete();
00165 }
00166 
00167 inline bool BValueMap::IsShared() const
00168 {
00169     return m_users > 1;
00170 }
00171 
00172 inline ssize_t BValueMap::ArchivedSize() const
00173 {
00174     if (m_dataSize >= 0) return m_dataSize;
00175     return ComputeArchivedSize();
00176 }
00177 
00178 inline ssize_t BValueMap::IndexFor(const SValue& key, const SValue& value) const
00179 {
00180     size_t index;
00181     return GetIndexOf(key, value, &index) ? index : B_NAME_NOT_FOUND;
00182 }
00183 
00184 inline ssize_t BValueMap::IndexFor(uint32_t type, const void* data, size_t length) const
00185 {
00186     size_t index;
00187     return GetIndexOf(type, data, length, &index) ? index : B_NAME_NOT_FOUND;
00188 }
00189 
00190 inline const BValueMap::pair& BValueMap::MapAt(size_t index) const
00191 {
00192     return m_maps[index];
00193 }
00194 
00195 inline size_t BValueMap::CountMaps() const
00196 {
00197     return m_size;
00198 }
00199 
00200 inline bool BValueMap::IsEditing() const
00201 {
00202     return m_editIndex >= 0;
00203 }
00204 
00205 inline void BValueMap::AssertEditing() const
00206 {
00207     ErrFatalErrorIf(IsEditing(), "This operation can not be performed while editing a value");
00208 }
00209 
00210 #if _SUPPORTS_NAMESPACE
00211 } } // namespace palmos::support
00212 #endif
00213 #endif