Update ooo320-m1
[ooovba.git] / configmgr / source / treecache / cacheaccess.cxx
blob831cd0f2f41f60d051e1f8778e9f1d4af73eed73
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cacheaccess.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
34 #include "cacheaccess.hxx"
35 #include "tracer.hxx"
36 #include "configpath.hxx"
38 namespace configmgr
40 // -------------------------------------------------------------------------
42 CacheClientAccess::CacheClientAccess(ConfigChangeBroadcastHelper * _pBroadcastHelper)
43 : m_pBroadcastHelper( _pBroadcastHelper )
46 // -------------------------------------------------------------------------
48 CacheClientAccess::~CacheClientAccess()
50 OSL_ENSURE(!m_pBroadcastHelper, "Forgot to dispose broadcast helper");
52 // -------------------------------------------------------------------------
54 ConfigChangeBroadcastHelper * CacheClientAccess::releaseBroadcaster()
56 ConfigChangeBroadcastHelper * pRet = m_pBroadcastHelper;
57 m_pBroadcastHelper = NULL;
58 return pRet;
61 // -------------------------------------------------------------------------
63 bool CacheClientAccess::hasModule(const configuration::AbsolutePath& _aLocation)
65 return this->m_aData.hasModule(_aLocation.getModuleName());
67 // -------------------------------------------------------------------------
69 bool CacheClientAccess::hasModuleDefaults(configuration::AbsolutePath const& _aLocation)
71 return this->m_aData.hasModuleDefaults(_aLocation.getModuleName());
73 // -------------------------------------------------------------------------
74 void CacheClientAccess::attachModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aModule)
76 this->m_aData.attachModule(_aLocation, _aModule);
78 // -------------------------------------------------------------------------
80 sharable::Node * CacheClientAccess::acquireNode(configuration::AbsolutePath const& rLocation )
82 CFG_TRACE_INFO("CacheClientAccess: Requesting data for path '%s'", OUSTRING2ASCII(rLocation.toString()) );
84 sharable::Node * aResult = this->m_aData.acquireNode(rLocation);
86 if (aResult != NULL)
88 CFG_TRACE_INFO_NI("- Data is available - returning Subtree");
90 else
91 CFG_TRACE_INFO_NI("- Data is not available - returning NULL");
93 return aResult;
95 // -------------------------------------------------------------------------
97 oslInterlockedCount CacheClientAccess::releaseNode( configuration::AbsolutePath const& rLocation )
99 CFG_TRACE_INFO("Tree Info: Releasing subtree data for path '%s'", OUSTRING2ASCII(rLocation.toString()) );
101 oslInterlockedCount nRet = this->m_aData.releaseModule(rLocation.getModuleName(),false);
103 return nRet;
105 // -----------------------------------------------------------------------------
107 void CacheClientAccess::applyUpdate(backend::UpdateInstance & _aUpdate) SAL_THROW((com::sun::star::uno::RuntimeException))
109 CFG_TRACE_INFO("CacheClientAccess: Merging changes into subtree '%s'", OUSTRING2ASCII(_aUpdate.root().toString()) );
111 this->m_aData.applyUpdate(_aUpdate );
114 // -----------------------------------------------------------------------------
115 sharable::Node * CacheClientAccess::findInnerNode( configuration::AbsolutePath const& aComponentName )
117 sharable::Node * node = m_aData.getNode(aComponentName);
118 return node == 0 || node->isValue() ? 0 : node;
121 // -------------------------------------------------------------------------
123 bool CacheClientAccess::insertDefaults( backend::NodeInstance const & _aDefaultData ) SAL_THROW((com::sun::star::uno::RuntimeException))
125 CFG_TRACE_INFO("Tree Info: Adding default data for path '%s'", OUSTRING2ASCII(_aDefaultData.root().toString()) );
127 return this->m_aData.insertDefaults(_aDefaultData);
129 // -------------------------------------------------------------------------
131 // -------------------------------------------------------------------------
132 // -------------------------------------------------------------------------
134 CacheLoadingAccess::CacheLoadingAccess()
135 : m_aDeadModules()
138 // -------------------------------------------------------------------------
140 CacheLoadingAccess::~CacheLoadingAccess()
144 // -------------------------------------------------------------------------
146 /// gets a tree reference for the given path if exists
147 sharable::TreeFragment * CacheLoadingAccess::getTreeAddress(rtl::OUString const & _aModule)
149 return this->m_aData.getTreeAddress(_aModule);
151 // -------------------------------------------------------------------------
152 void CacheLoadingAccess::createModule(rtl::OUString const & _aModule)
154 this->m_aData.createModule(_aModule);
156 // -------------------------------------------------------------------------
157 bool CacheLoadingAccess::hasModule(rtl::OUString const & _aModule)
159 return this->m_aData.hasModule(_aModule);
161 // -------------------------------------------------------------------------
163 bool CacheLoadingAccess::acquireModule(rtl::OUString const & _aModule)
165 CFG_TRACE_INFO("Tree Info: Requesting data for module '%s'", OUSTRING2ASCII(_aModule));
167 if (this->m_aData.acquireModule(_aModule))
169 m_aDeadModules.erase( _aModule );
170 CFG_TRACE_INFO_NI("- Data is available - returning Subtree");
171 return true;
173 else
175 CFG_TRACE_INFO_NI("- Data is not available - returning NULL");
176 return false;
179 // -------------------------------------------------------------------------
181 oslInterlockedCount CacheLoadingAccess::releaseModule( rtl::OUString const & _aModule )
183 CFG_TRACE_INFO("Tree Info: Releasing data for module '%s'", OUSTRING2ASCII(_aModule) );
185 oslInterlockedCount nRet = this->m_aData.releaseModule(_aModule,true); // keep
186 if (nRet == 0)
188 m_aDeadModules[ _aModule ] = TimeStamp::getCurrentTime();
189 CFG_TRACE_INFO_NI("- Last reference released - marking data for cleanup");
192 return nRet;
194 // -----------------------------------------------------------------------------
196 bool CacheLoadingAccess::isEmpty()
198 ExtendedCacheData::ModuleList& rModules = this->m_aData.accessModuleList();
200 bool bRet = rModules.empty();
202 if (bRet) // while we are at it - clean up
203 m_aDeadModules.clear();
205 return bRet;
207 // -------------------------------------------------------------------------
209 sharable::TreeFragment * CacheLoadingAccess::addComponentData( backend::ComponentInstance const & _aComponentInstance,
210 bool _bIncludesDefaults
211 ) SAL_THROW((com::sun::star::uno::RuntimeException))
213 CFG_TRACE_INFO("CacheLoadingAccess: Adding component data for module '%s' : %s",
214 OUSTRING2ASCII(_aComponentInstance.component()),
215 _bIncludesDefaults ? "Data includes defaults." : "Data does not include defaults." );
217 sharable::TreeFragment * aResult = this->m_aData.addComponentData(_aComponentInstance, _bIncludesDefaults);
218 if (aResult != NULL)
220 m_aDeadModules.erase( _aComponentInstance.component() );
221 CFG_TRACE_INFO_NI("- Data added successfully - returning Subtree");
223 else
224 CFG_TRACE_INFO_NI("- Data not added - returning NULL");
226 return aResult;
228 // -------------------------------------------------------------------------
229 // -----------------------------------------------------------------------------
230 void CacheLoadingAccess::addChangesToPending( backend::ConstUpdateInstance const& _anUpdate ) SAL_THROW((com::sun::star::uno::RuntimeException))
232 // NICE: m_pPending[_rLocation] += pSubtreeChange;
233 CFG_TRACE_INFO("CacheLoadingAccess: Adding pending changes for subtree '%s'", OUSTRING2ASCII(_anUpdate.root().toString()) );
235 this->m_aData.addPending(_anUpdate);
238 // -----------------------------------------------------------------------------
239 std::auto_ptr<SubtreeChange> CacheLoadingAccess::releasePendingChanges(rtl::OUString const& _aComponentName)
241 CFG_TRACE_INFO("Tree Info: extract pending changes from subtree '%s'", OUSTRING2ASCII(_aComponentName) );
242 return this->m_aData.releasePending(_aComponentName);
245 // -----------------------------------------------------------------------------
246 bool CacheLoadingAccess::findPendingChangedModules( std::vector< rtl::OUString > & _rPendingList )
248 this->m_aData.findPendingModules(_rPendingList);
249 return !_rPendingList.empty();
252 // -------------------------------------------------------------------------
254 TimeStamp CacheLoadingAccess::collectDisposeList(std::vector< rtl::Reference<CacheLine> > & _rList, TimeStamp const & _aLimitTime, TimeInterval const & _aDelay)
256 TimeStamp aRetTime = TimeStamp::never();
258 CFG_TRACE_INFO("Tree Info: Collecting disposable module trees for cleanup" );
260 ExtendedCacheData::ModuleList& rActiveModules = this->m_aData.accessModuleList();
262 std::map< rtl::OUString, TimeStamp >::iterator it = m_aDeadModules.begin();
264 while (it != m_aDeadModules.end())
266 std::map< rtl::OUString, TimeStamp >::iterator current = it;
267 // increment here, as we may later erase(current)
268 ++it;
270 #if (OSL_DEBUG_LEVEL > 0) || defined _DBG_UTIL || defined CFG_TRACE_ENABLE
271 rtl::OUString sCurrentName( current->first );
272 #endif
273 TimeStamp aExpireTime = current->second + _aDelay;
274 if (aExpireTime <= _aLimitTime)
276 ExtendedCacheData::ModuleList::iterator itModule = rActiveModules.find( current->first );
278 if (itModule != rActiveModules.end())
280 rtl::Reference<CacheLine> xModule = itModule->second;
282 bool bHandled = false;
284 if (!xModule.is())
286 CFG_TRACE_ERROR_NI("- Unexpected: Module '%s' is NULL in active module list", OUSTRING2ASCII(sCurrentName) );
287 bHandled = true;
289 else if (xModule->clientReferences() != 0)// at least in temporary use
291 OSL_ENSURE( false, "Referenced entry in dead module list");
293 CFG_TRACE_WARNING_NI("- Module '%s' in (temporary ?) use - rescheduling", OUSTRING2ASCII(sCurrentName) );
294 bHandled = false; // still remove from the lists
296 else if (m_aData.hasPending(current->first))
298 CFG_TRACE_WARNING_NI("- Module '%s' has pending changes - rescheduling disposal", OUSTRING2ASCII(sCurrentName) );
299 bHandled = false;
301 else // now this really can be disposed
303 CFG_TRACE_INFO_NI("- Removing module '%s' for disposal", OUSTRING2ASCII(sCurrentName) );
305 // It really is ok to dispose this entry
306 _rList.push_back(xModule);
308 bHandled = true;
312 if (bHandled)
314 // really remove
315 rActiveModules.erase(itModule);
316 m_aDeadModules.erase(current);
318 else
320 // reschedule
321 TimeStamp aRetryTime = _aLimitTime + _aDelay;
322 OSL_ASSERT(aRetryTime > _aLimitTime);
324 current->second = _aLimitTime; // ?
325 if (aRetryTime < aRetTime)
326 aRetTime = aRetryTime;
329 else
331 // obsolete dispose list entry - discard
332 OSL_ENSURE( false, "Obsolete entry in dead module list");
334 CFG_TRACE_WARNING_NI("- Module '%s' not found any more - obsolete entry in dead module list", OUSTRING2ASCII(sCurrentName) );
336 m_aDeadModules.erase(current);
339 else // consider for restart time
341 CFG_TRACE_INFO_NI("- Module '%s' has not expired yet - rescheduling", OUSTRING2ASCII(sCurrentName) );
343 if (aExpireTime < aRetTime)
344 aRetTime = aExpireTime;
348 OSL_ASSERT(aRetTime > _aLimitTime);
349 return aRetTime;
351 // -------------------------------------------------------------------------
353 } // namespace configmgr