GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: StringPool.cpp 471747 2006-11-06 14:31:56Z amassari $ 00020 */ 00021 00022 00023 // --------------------------------------------------------------------------- 00024 // Includes 00025 // --------------------------------------------------------------------------- 00026 #include <xercesc/util/StringPool.hpp> 00027 #include <assert.h> 00028 00029 XERCES_CPP_NAMESPACE_BEGIN 00030 00031 // --------------------------------------------------------------------------- 00032 // XMLStringPool: Constructors and Destructor 00033 // --------------------------------------------------------------------------- 00034 XMLStringPool::XMLStringPool(const unsigned int modulus, 00035 MemoryManager* const manager) : 00036 00037 fMemoryManager(manager) 00038 , fIdMap(0) 00039 , fHashTable(0) 00040 , fMapCapacity(64) 00041 , fCurId(1) 00042 { 00043 // Create the hash table, passing it the modulus 00044 fHashTable = new (fMemoryManager) RefHashTableOf<PoolElem>(modulus, false, fMemoryManager); 00045 00046 // Do an initial allocation of the id map and zero it all out 00047 fIdMap = (PoolElem**) fMemoryManager->allocate 00048 ( 00049 fMapCapacity * sizeof(PoolElem*) 00050 ); //new PoolElem*[fMapCapacity]; 00051 memset(fIdMap, 0, sizeof(PoolElem*) * fMapCapacity); 00052 } 00053 00054 XMLStringPool::~XMLStringPool() 00055 { 00056 // delete all buckelements, since the hashtable doesn't adopt the elements anymore 00057 for (unsigned int index = 1; index < fCurId; index++) 00058 { 00059 //fIdMap[index]->~PoolElem(); // we have no destructor 00060 fMemoryManager->deallocate((void*) fIdMap[index]->fString); // deallocate memory 00061 fMemoryManager->deallocate(fIdMap[index]); // deallocate memory 00062 } 00063 delete fHashTable; 00064 fMemoryManager->deallocate(fIdMap); //delete [] fIdMap; 00065 } 00066 00067 // --------------------------------------------------------------------------- 00068 // XMLStringPool: Pool management methods 00069 // --------------------------------------------------------------------------- 00070 void XMLStringPool::flushAll() 00071 { 00072 // delete all buckelements, since the hashtable doesn't adopt the elements anymore 00073 for (unsigned int index = 1; index < fCurId; index++) 00074 { 00075 //fIdMap[index]->~PoolElem(); // we have no destructor 00076 fMemoryManager->deallocate((void*) fIdMap[index]->fString); // deallocate memory 00077 fMemoryManager->deallocate(fIdMap[index]); // deallocate memory 00078 } 00079 fCurId = 1; 00080 fHashTable->removeAll(); 00081 } 00082 00083 // --------------------------------------------------------------------------- 00084 // XMLStringPool: Private helper methods 00085 // --------------------------------------------------------------------------- 00086 unsigned int XMLStringPool::addNewEntry(const XMLCh* const newString) 00087 { 00088 // See if we need to expand the id map 00089 if (fCurId == fMapCapacity) 00090 { 00091 // Calculate the new capacity, create a temp new map, and zero it 00092 const unsigned int newCap = (unsigned int)(fMapCapacity * 1.5); 00093 PoolElem** newMap = (PoolElem**) fMemoryManager->allocate 00094 ( 00095 newCap * sizeof(PoolElem*) 00096 ); //new PoolElem*[newCap]; 00097 memset(newMap, 0, sizeof(PoolElem*) * newCap); 00098 00099 // 00100 // Copy over the old elements from the old map. They are just pointers 00101 // so we can do it all at once. 00102 // 00103 memcpy(newMap, fIdMap, sizeof(PoolElem*) * fMapCapacity); 00104 00105 // Clean up the old map and store the new info 00106 fMemoryManager->deallocate(fIdMap); //delete [] fIdMap; 00107 fIdMap = newMap; 00108 fMapCapacity = newCap; 00109 } 00110 00111 // 00112 // Ok, now create a new element and add it to the hash table. Then store 00113 // this new element in the id map at the current id index, then bump the 00114 // id index. 00115 // 00116 PoolElem* newElem = (PoolElem*) fMemoryManager->allocate(sizeof(PoolElem)); 00117 newElem->fId = fCurId; 00118 newElem->fString = XMLString::replicate(newString, fMemoryManager); 00119 fHashTable->put((void*)newElem->fString, newElem); 00120 fIdMap[fCurId] = newElem; 00121 00122 // Bump the current id and return the id of the new elem we just added 00123 fCurId++; 00124 return newElem->fId; 00125 } 00126 00127 /*** 00128 * Support for Serialization/De-serialization 00129 ***/ 00130 00131 IMPL_XSERIALIZABLE_TOCREATE(XMLStringPool) 00132 00133 void XMLStringPool::serialize(XSerializeEngine& serEng) 00134 { 00135 /*** 00136 * Since we are pretty sure that fIdMap and fHashTable is 00137 * not shared by any other object, therefore there is no owned/referenced 00138 * issue. Thus we can serialize the raw data only, rather than serializing 00139 * both fIdMap and fHashTable. 00140 * 00141 * And we can rebuild the fIdMap and fHashTable out of the raw data during 00142 * deserialization. 00143 * 00144 ***/ 00145 if (serEng.isStoring()) 00146 { 00147 serEng<<fCurId; 00148 for (unsigned int index = 1; index < fCurId; index++) 00149 { 00150 const XMLCh* stringData = getValueForId(index); 00151 serEng.writeString(stringData); 00152 } 00153 } 00154 else 00155 { 00156 unsigned int mapSize; 00157 serEng>>mapSize; 00158 assert(1 == fCurId); //make sure empty 00159 00160 for (unsigned int index = 1; index < mapSize; index++) 00161 { 00162 XMLCh* stringData; 00163 serEng.readString(stringData); 00164 addNewEntry(stringData); 00165 00166 //we got to deallocate this string 00167 //since stringpool will duplicate this string in the PoolElem and own that copy 00168 fMemoryManager->deallocate(stringData); 00169 } 00170 } 00171 } 00172 00173 XMLStringPool::XMLStringPool(MemoryManager* const manager) : 00174 fMemoryManager(manager) 00175 , fIdMap(0) 00176 , fHashTable(0) 00177 , fMapCapacity(64) 00178 , fCurId(1) 00179 { 00180 // Create the hash table, passing it the modulus 00181 fHashTable = new (fMemoryManager) RefHashTableOf<PoolElem>(109, false, fMemoryManager); 00182 00183 // Do an initial allocation of the id map and zero it all out 00184 fIdMap = (PoolElem**) fMemoryManager->allocate 00185 ( 00186 fMapCapacity * sizeof(PoolElem*) 00187 ); //new PoolElem*[fMapCapacity]; 00188 memset(fIdMap, 0, sizeof(PoolElem*) * fMapCapacity); 00189 } 00190 00191 XERCES_CPP_NAMESPACE_END