/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id$ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include XERCES_CPP_NAMESPACE_BEGIN // --------------------------------------------------------------------------- // XMLStringPool: Constructors and Destructor // --------------------------------------------------------------------------- XMLStringPool::XMLStringPool(const unsigned int modulus, MemoryManager* const manager) : fMemoryManager(manager) , fIdMap(0) , fHashTable(0) , fMapCapacity(64) , fCurId(1) { // Create the hash table, passing it the modulus fHashTable = new (fMemoryManager) RefHashTableOf(modulus, false, fMemoryManager); // Do an initial allocation of the id map and zero it all out fIdMap = (PoolElem**) fMemoryManager->allocate ( fMapCapacity * sizeof(PoolElem*) ); //new PoolElem*[fMapCapacity]; memset(fIdMap, 0, sizeof(PoolElem*) * fMapCapacity); } XMLStringPool::~XMLStringPool() { // delete all buckelements, since the hashtable doesn't adopt the elements anymore for (unsigned int index = 1; index < fCurId; index++) { //fIdMap[index]->~PoolElem(); // we have no destructor fMemoryManager->deallocate((void*) fIdMap[index]->fString); // deallocate memory fMemoryManager->deallocate(fIdMap[index]); // deallocate memory } delete fHashTable; fMemoryManager->deallocate(fIdMap); //delete [] fIdMap; } // --------------------------------------------------------------------------- // XMLStringPool: Pool management methods // --------------------------------------------------------------------------- void XMLStringPool::flushAll() { // delete all buckelements, since the hashtable doesn't adopt the elements anymore for (unsigned int index = 1; index < fCurId; index++) { //fIdMap[index]->~PoolElem(); // we have no destructor fMemoryManager->deallocate((void*) fIdMap[index]->fString); // deallocate memory fMemoryManager->deallocate(fIdMap[index]); // deallocate memory } fCurId = 1; fHashTable->removeAll(); } // --------------------------------------------------------------------------- // XMLStringPool: Private helper methods // --------------------------------------------------------------------------- unsigned int XMLStringPool::addNewEntry(const XMLCh* const newString) { // See if we need to expand the id map if (fCurId == fMapCapacity) { // Calculate the new capacity, create a temp new map, and zero it const unsigned int newCap = (unsigned int)(fMapCapacity * 1.5); PoolElem** newMap = (PoolElem**) fMemoryManager->allocate ( newCap * sizeof(PoolElem*) ); //new PoolElem*[newCap]; memset(newMap, 0, sizeof(PoolElem*) * newCap); // // Copy over the old elements from the old map. They are just pointers // so we can do it all at once. // memcpy(newMap, fIdMap, sizeof(PoolElem*) * fMapCapacity); // Clean up the old map and store the new info fMemoryManager->deallocate(fIdMap); //delete [] fIdMap; fIdMap = newMap; fMapCapacity = newCap; } // // Ok, now create a new element and add it to the hash table. Then store // this new element in the id map at the current id index, then bump the // id index. // PoolElem* newElem = (PoolElem*) fMemoryManager->allocate(sizeof(PoolElem)); newElem->fId = fCurId; newElem->fString = XMLString::replicate(newString, fMemoryManager); fHashTable->put((void*)newElem->fString, newElem); fIdMap[fCurId] = newElem; // Bump the current id and return the id of the new elem we just added fCurId++; return newElem->fId; } /*** * Support for Serialization/De-serialization ***/ IMPL_XSERIALIZABLE_TOCREATE(XMLStringPool) void XMLStringPool::serialize(XSerializeEngine& serEng) { /*** * Since we are pretty sure that fIdMap and fHashTable is * not shared by any other object, therefore there is no owned/referenced * issue. Thus we can serialize the raw data only, rather than serializing * both fIdMap and fHashTable. * * And we can rebuild the fIdMap and fHashTable out of the raw data during * deserialization. * ***/ if (serEng.isStoring()) { serEng<>mapSize; assert(1 == fCurId); //make sure empty for (unsigned int index = 1; index < mapSize; index++) { XMLCh* stringData; serEng.readString(stringData); addNewEntry(stringData); //we got to deallocate this string //since stringpool will duplicate this string in the PoolElem and own that copy fMemoryManager->deallocate(stringData); } } } XMLStringPool::XMLStringPool(MemoryManager* const manager) : fMemoryManager(manager) , fIdMap(0) , fHashTable(0) , fMapCapacity(64) , fCurId(1) { // Create the hash table, passing it the modulus fHashTable = new (fMemoryManager) RefHashTableOf(109, false, fMemoryManager); // Do an initial allocation of the id map and zero it all out fIdMap = (PoolElem**) fMemoryManager->allocate ( fMapCapacity * sizeof(PoolElem*) ); //new PoolElem*[fMapCapacity]; memset(fIdMap, 0, sizeof(PoolElem*) * fMapCapacity); } XERCES_CPP_NAMESPACE_END