First public contribution.
1 // Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "SqlAssert.h"
17 #include "SqlCompact.h"
18 #include "SqlCompactEntry.h"
19 #include "SqlCompactTimer.h"
21 #include "OstTraceDefinitions.h"
22 #ifdef OST_TRACE_COMPILER_IN_USE
23 #include "SqlCompactTraces.h"
25 #include "SqlTraceDef.h"
27 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
29 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 Initializes the background compaction settings with their default values.
34 TSqlCompactSettings::TSqlCompactSettings() :
35 iStepLength(KSqlCompactStepLengthMs),
36 iFreePageThresholdKb(KSqlCompactFreePageThresholdKb)
42 CSqlCompactSettings invariant.
44 void TSqlCompactSettings::Invariant() const
46 __ASSERT_DEBUG(iStepLength > 0, __SQLPANIC(ESqlPanicInternalError));
47 __ASSERT_DEBUG(iFreePageThresholdKb >= 0, __SQLPANIC(ESqlPanicInternalError));
51 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
52 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
53 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
56 The granularity of the container maintained by CSqlCompactor
61 const TInt KEntriesGranularity = 16;
64 Creates a new CSqlCompactor instance.
66 @param aConnFactoryL MSqlCompactConn factory function.
67 @param aCompactStepInterval The time interval (ms) between the background compaction steps.
69 @return A pointer to the created CSqlCompactor instance
71 @leave KErrNoMemory, an out of memory condition has occurred;
72 Note that the function may also leave with some other database specific
73 errors categorised as ESqlDbError, and other system-wide error codes.
75 @panic SqlDb 4 In _DEBUG mode. NULL aConnFactoryL.
76 @panic SqlDb 4 In _DEBUG mode. Zero or negative aCompactStepInterval.
78 CSqlCompactor* CSqlCompactor::NewL(TSqlCompactConnFactoryL aConnFactoryL, TInt aCompactStepInterval)
80 __ASSERT_DEBUG(aConnFactoryL != NULL, __SQLPANIC2(ESqlPanicBadArgument));
81 __ASSERT_DEBUG(aCompactStepInterval > 0, __SQLPANIC2(ESqlPanicBadArgument));
82 CSqlCompactor* self = new (ELeave) CSqlCompactor(aConnFactoryL);
83 CleanupStack::PushL(self);
84 self->ConstructL(aCompactStepInterval);
85 CleanupStack::Pop(self);
90 Destroys the CSqlCompactor instance.
91 Any entries left in the container will be destroyed.
93 CSqlCompactor::~CSqlCompactor()
95 for(TInt idx=iEntries.Count()-1;idx>=0;--idx)
97 __ASSERT_DEBUG(iEntries[idx] != NULL, __SQLPANIC(ESqlPanicInternalError));
98 while(iEntries[idx]->Release() != 0)
107 Restarts the background compaction timer.
108 This function should be called from the server side session object's ServiceL().
109 If ServiceL() is being executed at the moment, it is very likely that the SQL client(s) will issue another
110 request few ms later. In order to not delay the processing of the client(s) requests, ServiceL() should call
111 at the end RestartTimer(). If there are database entries scheduled for a background compaction, the compaction
112 will be delayed by the time interval used by the CSqlCompactTimer object (default value - KSqlCompactStepInterval).
114 @see CSqlCompactTimer
115 @see KSqlCompactStepInterval
117 void CSqlCompactor::RestartTimer()
119 SQLCOMPACTOR_INVARIANT();
121 SQLCOMPACTOR_INVARIANT();
125 If an entry referring to a database with name aFullName does not exist in the container, a new entry will be created,
126 a connection with the database established.
127 If an entry with the specified name already exists, no new entry wil be created, the reference counter of the existing one
130 @param aFullName The full database name, including the path.
131 @param aSettings Per-database background compaction settings
133 @leave KErrNoMemory, an out of memory condition has occurred;
134 Note that the function may also leave with some other database specific
135 errors categorised as ESqlDbError, and other system-wide error codes.
137 @panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
138 @panic SqlDb 7 In _DEBUG mode. An entry with the specified name has been found but the entry is NULL.
140 void CSqlCompactor::AddEntryL(const TDesC& aFullName, const TSqlCompactSettings& aSettings)
142 __ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC(ESqlPanicBadArgument));
143 SQLCOMPACTOR_INVARIANT();
144 CSqlCompactEntry* entry = NULL;
145 TInt idx = iEntries.FindInOrder(aFullName, &CSqlCompactor::Search);
146 if(idx == KErrNotFound)
148 SQL_TRACE_COMPACT(OstTraceExt4(TRACE_INTERNALS, CSQLCOMPACTOR_ADDENTRYL1, "0x%X;CSqlCompactor::AddEntryL;New entry;aFullName=%S;iStepLength=%d;iFreePageThreashold=%d", (TUint)this, __SQLPRNSTR(aFullName), aSettings.iStepLength, aSettings.iFreePageThresholdKb));
149 entry = CSqlCompactEntry::NewLC(aFullName, iConnFactoryL, aSettings, *iTimer);
150 TLinearOrder<CSqlCompactEntry> order(&CSqlCompactor::Compare);
151 __SQLLEAVE_IF_ERROR(iEntries.InsertInOrder(entry, order));
152 CleanupStack::Pop(entry);
156 SQL_TRACE_COMPACT(OstTraceExt4(TRACE_INTERNALS, CSQLCOMPACTOR_ADDENTRYL2, "0x%X;CSqlCompactor::AddEntryL;Reuse entry;aFullName=%S;iStepLength=%d;iFreePageThreashold=%d", (TUint)this, __SQLPRNSTR(aFullName), aSettings.iStepLength, aSettings.iFreePageThresholdKb));
157 entry = iEntries[idx];
158 __ASSERT_DEBUG(entry != NULL, __SQLPANIC(ESqlPanicInternalError));
159 (void)entry->AddRef();
161 SQLCOMPACTOR_INVARIANT();
165 Decrements the reference counter of the specified entry.
166 If the counter reaches zero, the entry will be destroyed and removed from the container,
167 the database connection - closed.
169 @param aFullName The full database name, including the path.
171 void CSqlCompactor::ReleaseEntry(const TDesC& aFullName)
173 SQL_TRACE_COMPACT(OstTraceExt2(TRACE_INTERNALS, CSQLCOMPACTOR_RELEASEENTRY1, "0x%X;CSqlCompactor::ReleaseEntry;aFullName=%S", (TUint)this, __SQLPRNSTR(aFullName)));
174 SQLCOMPACTOR_INVARIANT();
175 TInt idx = iEntries.FindInOrder(aFullName, &CSqlCompactor::Search);
176 __ASSERT_DEBUG(idx >= 0, __SQLPANIC(ESqlPanicInternalError));
179 CSqlCompactEntry* entry = iEntries[idx];
180 __ASSERT_DEBUG(entry != NULL, __SQLPANIC(ESqlPanicInternalError));
183 if(entry->Release() == 0)
185 iEntries.Remove(idx);
187 //This is used prevent the failure of the resource allocation checking for debug mode.
188 if(iEntries.Count() == 0)
196 SQLCOMPACTOR_INVARIANT();
200 Initializes the CSqlCompactor data members with their default values.
202 @param aConnFactoryL MSqlCompactConn factory function.
204 @panic SqlDb 4 In _DEBUG mode. NULL aConnFactoryL.
206 CSqlCompactor::CSqlCompactor(TSqlCompactConnFactoryL aConnFactoryL) :
207 iConnFactoryL(aConnFactoryL),
208 iEntries(KEntriesGranularity)
210 __ASSERT_DEBUG(aConnFactoryL != NULL, __SQLPANIC(ESqlPanicBadArgument));
214 Initializes the created CSqlCompactor instance.
216 @param aCompactStepInterval The time interval between the background compaction steps.
218 @panic SqlDb 4 In _DEBUG mode. Zero or negative aCompactStepInterval.
220 void CSqlCompactor::ConstructL(TInt aCompactStepInterval)
222 __ASSERT_DEBUG(aCompactStepInterval > 0, __SQLPANIC(ESqlPanicBadArgument));
223 iTimer = CSqlCompactTimer::NewL(aCompactStepInterval);
227 Static method used internally for performing a search in the container using database name as a key.
229 @param aFullName The full database name, including the path.
230 @param aEntry CSqlCompactor reference.
232 /* static */TInt CSqlCompactor::Search(const TDesC* aFullName, const CSqlCompactEntry& aEntry)
234 __ASSERT_DEBUG(&aEntry != NULL, __SQLPANIC2(ESqlPanicInternalError));
235 __ASSERT_DEBUG(aFullName != NULL, __SQLPANIC2(ESqlPanicInternalError));
236 const TDesC& fullName = *aFullName;
237 __ASSERT_DEBUG(fullName.Length() > 0 && fullName.Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicInternalError));
238 __ASSERT_DEBUG(aEntry.FullName().Length() > 0 && aEntry.FullName().Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicInternalError));
239 return fullName.CompareF(aEntry.FullName());
243 Static method used internally for performing a search in the container using a CSqlCompactEntry reference as a key.
245 /* static */TInt CSqlCompactor::Compare(const CSqlCompactEntry& aLeft, const CSqlCompactEntry& aRight)
247 __ASSERT_DEBUG(&aLeft != NULL, __SQLPANIC2(ESqlPanicInternalError));
248 __ASSERT_DEBUG(&aRight != NULL, __SQLPANIC2(ESqlPanicInternalError));
249 __ASSERT_DEBUG(aLeft.FullName().Length() > 0 && aLeft.FullName().Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicInternalError));
250 __ASSERT_DEBUG(aRight.FullName().Length() > 0 && aRight.FullName().Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicInternalError));
251 return aLeft.FullName().CompareF(aRight.FullName());
256 CSqlCompactor invariant.
258 void CSqlCompactor::Invariant() const
260 __ASSERT_DEBUG(iConnFactoryL != NULL, __SQLPANIC(ESqlPanicInternalError));
261 __ASSERT_DEBUG(iTimer != NULL, __SQLPANIC(ESqlPanicInternalError));
263 for(TInt idx=iEntries.Count()-1;idx>=0;--idx)
265 __ASSERT_DEBUG(iEntries[idx] != NULL, __SQLPANIC(ESqlPanicInternalError));
266 iEntries[idx]->Invariant();