GME  13
ValueStoreCache.cpp
Go to the documentation of this file.
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: ValueStoreCache.cpp 708224 2008-10-27 16:02:26Z amassari $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include <xercesc/validators/schema/identity/ValueStoreCache.hpp>
00026 #include <xercesc/validators/schema/identity/ValueStore.hpp>
00027 #include <xercesc/validators/schema/SchemaElementDecl.hpp>
00028 #include <xercesc/util/OutOfMemoryException.hpp>
00029 
00030 XERCES_CPP_NAMESPACE_BEGIN
00031 
00032 typedef JanitorMemFunCall<ValueStoreCache>    CleanupType;
00033 
00034 // ---------------------------------------------------------------------------
00035 //  ValueStoreCache: Constructors and Destructor
00036 // ---------------------------------------------------------------------------
00037 ValueStoreCache::ValueStoreCache(MemoryManager* const manager)
00038     : fValueStores(0)
00039     , fGlobalICMap(0)
00040     , fIC2ValueStoreMap(0)
00041     , fGlobalMapStack(0)
00042     , fScanner(0)
00043     , fMemoryManager(manager)
00044 {
00045     CleanupType cleanup(this, &ValueStoreCache::cleanUp);
00046 
00047     try {
00048         init();
00049     }
00050     catch(const OutOfMemoryException&)
00051     {
00052         cleanup.release();
00053 
00054         throw;
00055     }
00056 
00057     cleanup.release();
00058 }
00059 
00060 
00061 ValueStoreCache::~ValueStoreCache()
00062 {
00063     cleanUp();
00064 }
00065 
00066 // ---------------------------------------------------------------------------
00067 //  ValueStoreCache: Document handling methods
00068 // ---------------------------------------------------------------------------
00069 void ValueStoreCache::startDocument() {
00070 
00071     fIC2ValueStoreMap->removeAll();
00072     fGlobalICMap->removeAll();
00073     fValueStores->removeAllElements();
00074     fGlobalMapStack->removeAllElements();
00075 }
00076 
00077 void ValueStoreCache::startElement() {
00078 
00079     fGlobalMapStack->push(fGlobalICMap);
00080     fGlobalICMap = new (fMemoryManager) RefHashTableOf<ValueStore, PtrHasher>
00081     (
00082         13
00083         , false
00084         , fMemoryManager
00085     );
00086 }
00087 
00088 void ValueStoreCache::endElement() {
00089 
00090     if (fGlobalMapStack->empty()) {
00091         return; // must be an invalid doc!
00092     }
00093 
00094     RefHashTableOf<ValueStore, PtrHasher>* oldMap = fGlobalMapStack->pop();
00095     RefHashTableOfEnumerator<ValueStore, PtrHasher> mapEnum(oldMap, false, fMemoryManager);
00096 //    Janitor<RefHashTableOf<ValueStore> > janMap(oldMap);
00097 
00098     while (mapEnum.hasMoreElements()) {
00099 
00100         ValueStore& oldVal = mapEnum.nextElement();
00101         IdentityConstraint* ic = oldVal.getIdentityConstraint();
00102         ValueStore* currVal = fGlobalICMap->get(ic);
00103 
00104         if (!currVal) {
00105             fGlobalICMap->put(ic, &oldVal);
00106         }
00107         else {
00108             currVal->append(&oldVal);
00109         }
00110     }
00111     delete oldMap;
00112 }
00113 
00114 // ---------------------------------------------------------------------------
00115 //  ValueStoreCache: Helper methods
00116 // ---------------------------------------------------------------------------
00117 void ValueStoreCache::cleanUp() {
00118 
00119     delete fIC2ValueStoreMap;
00120     delete fGlobalICMap;
00121     delete fGlobalMapStack;
00122     delete fValueStores;
00123 }
00124 
00125 void ValueStoreCache::init() {
00126 
00127     fValueStores = new (fMemoryManager) RefVectorOf<ValueStore>(8, false, fMemoryManager);
00128     fGlobalICMap = new (fMemoryManager) RefHashTableOf<ValueStore, PtrHasher>
00129     (
00130         13
00131         , false
00132         , fMemoryManager
00133     );
00134     fIC2ValueStoreMap = new (fMemoryManager) RefHash2KeysTableOf<ValueStore, PtrHasher>
00135     (
00136         13
00137         , true
00138         , fMemoryManager
00139     );
00140     fGlobalMapStack = new (fMemoryManager) RefStackOf<RefHashTableOf<ValueStore, PtrHasher> >(8, true, fMemoryManager);
00141 }
00142 
00143 void ValueStoreCache::initValueStoresFor(SchemaElementDecl* const elemDecl,
00144                                          const int initialDepth) {
00145 
00146     // initialize value stores for unique fields
00147     XMLSize_t icCount = elemDecl->getIdentityConstraintCount();
00148 
00149     for (XMLSize_t i=0; i<icCount; i++) {
00150 
00151         IdentityConstraint* ic = elemDecl->getIdentityConstraintAt(i);
00152         ValueStore* valueStore=fIC2ValueStoreMap->get(ic, initialDepth);
00153         if(valueStore==0)
00154         {
00155             valueStore = new (fMemoryManager) ValueStore(ic, fScanner, fMemoryManager);
00156             fIC2ValueStoreMap->put(ic, initialDepth, valueStore);
00157         }
00158         else
00159             valueStore->clear();
00160         fValueStores->addElement(valueStore);
00161     }
00162 }
00163 
00164 void ValueStoreCache::transplant(IdentityConstraint* const ic, const int initialDepth) {
00165 
00166     if (ic->getType() == IdentityConstraint::ICType_KEYREF) {
00167         return;
00168     }
00169 
00170     ValueStore* newVals = fIC2ValueStoreMap->get(ic, initialDepth);
00171     ValueStore* currVals = fGlobalICMap->get(ic);
00172 
00173     if (currVals) {
00174         currVals->append(newVals);
00175     } else {
00176         fGlobalICMap->put(ic, newVals);
00177     }
00178 }
00179 
00180 XERCES_CPP_NAMESPACE_END
00181