Newer
Older
* 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.
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/StringPool.hpp>
// ---------------------------------------------------------------------------
// XMLStringPool: Constructors and Destructor
// ---------------------------------------------------------------------------
XMLStringPool::XMLStringPool(const unsigned int modulus,
MemoryManager* const manager) :
fMemoryManager(manager)
, fHashTable(0)
, fMapCapacity(64)
, fCurId(1)
{
// Create the hash table, passing it the modulus
fHashTable = new (fMemoryManager) RefHashTableOf<PoolElem>(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
}
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;
}
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/***
* 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<<fCurId;
for (unsigned int index = 1; index < fCurId; index++)
{
const XMLCh* stringData = getValueForId(index);
serEng.writeString(stringData);
}
}
else
{
unsigned int mapSize;
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);
David Abram Cargill
committed
XMLStringPool::XMLStringPool(MemoryManager* const manager) :
fMemoryManager(manager)
, fIdMap(0)
, fHashTable(0)
, fMapCapacity(64)
, fCurId(1)
David Abram Cargill
committed
// Create the hash table, passing it the modulus
fHashTable = new (fMemoryManager) RefHashTableOf<PoolElem>(109, false, fMemoryManager);
David Abram Cargill
committed
// 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);