persistentstorage/sql/SRC/Server/Compact/SqlCompact.cpp
changeset 0 08ec8eefde2f
child 6 5ffdb8f2067f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2008-2009 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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "SqlPanic.h"
       
    17 #include "SqlCompact.h"
       
    18 #include "SqlCompactEntry.h"
       
    19 #include "SqlCompactTimer.h"
       
    20 #include "SqlUtil.h"
       
    21 
       
    22 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    23 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    24 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    25 
       
    26 /**
       
    27 Initializes the background compaction stettings with their default values.
       
    28 */
       
    29 TSqlCompactSettings::TSqlCompactSettings() :
       
    30 	iStepLength(KSqlCompactStepLengthMs),
       
    31 	iFreePageThresholdKb(KSqlCompactFreePageThresholdKb)
       
    32 	{
       
    33 	}
       
    34 
       
    35 #ifdef _DEBUG
       
    36 /**
       
    37 CSqlCompactSettings invariant.
       
    38 */
       
    39 void TSqlCompactSettings::Invariant() const
       
    40 	{
       
    41 	__SQLASSERT(iStepLength > 0, ESqlPanicInternalError);
       
    42 	__SQLASSERT(iFreePageThresholdKb >= 0, ESqlPanicInternalError);
       
    43 	}
       
    44 #endif//_DEBUG
       
    45 
       
    46 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    47 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    48 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    49 
       
    50 /**
       
    51 The granularity of the container maintained by CSqlCompactor
       
    52 
       
    53 @see CSqlCompactor
       
    54 @internalComponent
       
    55 */
       
    56 const TInt KEntriesGranularity = 16;
       
    57 
       
    58 /**
       
    59 Creates a new CSqlCompactor instance.
       
    60 
       
    61 @param aConnFactoryL MSqlCompactConn factory function.
       
    62 @param aCompactStepInterval The time intrerval (ms) between the background compaction steps.
       
    63 
       
    64 @return A pointer to the created CSqlCompactor instance
       
    65 
       
    66 @leave KErrNoMemory, an out of memory condition has occurred;
       
    67                      Note that the function may also leave with some other database specific 
       
    68                      errors categorised as ESqlDbError, and other system-wide error codes.
       
    69 
       
    70 @panic SqlDb 4 In _DEBUG mode. NULL aConnFactoryL.
       
    71 @panic SqlDb 4 In _DEBUG mode. Zero or negative aCompactStepInterval.
       
    72 */
       
    73 CSqlCompactor* CSqlCompactor::NewL(TSqlCompactConnFactoryL aConnFactoryL, TInt aCompactStepInterval)
       
    74 	{
       
    75 	__SQLASSERT(aConnFactoryL != NULL, ESqlPanicBadArgument);
       
    76 	__SQLASSERT(aCompactStepInterval > 0, ESqlPanicBadArgument);
       
    77 	CSqlCompactor* self = new (ELeave) CSqlCompactor(aConnFactoryL);
       
    78 	CleanupStack::PushL(self);
       
    79 	self->ConstructL(aCompactStepInterval);
       
    80 	CleanupStack::Pop(self);
       
    81 	return self;
       
    82 	}
       
    83 
       
    84 /**
       
    85 Destroys the CSqlCompactor instance. 
       
    86 Any entries left in the container will be destroyed.
       
    87 */
       
    88 CSqlCompactor::~CSqlCompactor()
       
    89 	{
       
    90 	for(TInt idx=iEntries.Count()-1;idx>=0;--idx)
       
    91 		{
       
    92 		__SQLASSERT(iEntries[idx] != NULL, ESqlPanicInternalError);
       
    93 		while(iEntries[idx]->Release() != 0)
       
    94 			{
       
    95 			}
       
    96 		}
       
    97 	iEntries.Close();
       
    98 	delete iTimer;
       
    99 	}
       
   100 
       
   101 /**
       
   102 Restarts the background compaction timer. 
       
   103 This function should be called from the server side session object's ServiceL(). 
       
   104 If ServiceL() is being executed at the moment, it is very likely that the SQL client(s) will issue another
       
   105 request few ms later. In order to not delay the processing of the client(s) requests, ServiceL() should call
       
   106 at the end RestartTimer(). If there are database entries scheduled for a background compaction, the compaction
       
   107 will be delayed by the time interval used by the CSqlCompactTimer object (default value - KSqlCompactStepInterval).
       
   108 
       
   109 @see CSqlCompactTimer
       
   110 @see KSqlCompactStepInterval
       
   111 */
       
   112 void CSqlCompactor::RestartTimer()
       
   113 	{
       
   114 	SQLCOMPACTOR_INVARIANT();
       
   115 	iTimer->Restart();
       
   116 	SQLCOMPACTOR_INVARIANT();
       
   117 	}
       
   118 
       
   119 /**
       
   120 If an entry referring to a database with name aFullName does not exist in the container, a new entry will be created,
       
   121 a connection with the database established.
       
   122 If an entry with the specidfied name already exists, no new entry wil be created, the reference counter of the existing one 
       
   123 will be incremented.
       
   124 
       
   125 @param aFullName The full database name, including the path.
       
   126 @param aSettings Per-database background compaction settings
       
   127 
       
   128 @leave KErrNoMemory, an out of memory condition has occurred;
       
   129                      Note that the function may also leave with some other database specific 
       
   130                      errors categorised as ESqlDbError, and other system-wide error codes.
       
   131 
       
   132 @panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
       
   133 @panic SqlDb 7 In _DEBUG mode. An entry with the specidfied name has been found but the entry is NULL.
       
   134 */
       
   135 void CSqlCompactor::AddEntryL(const TDesC& aFullName, const TSqlCompactSettings& aSettings)
       
   136 	{
       
   137 	__SQLASSERT(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, ESqlPanicBadArgument);
       
   138 	SQLCOMPACTOR_INVARIANT();
       
   139 	CSqlCompactEntry* entry = NULL;
       
   140 	TInt idx = iEntries.FindInOrder(aFullName, &CSqlCompactor::Search);
       
   141 	if(idx == KErrNotFound)
       
   142 		{
       
   143 		entry = CSqlCompactEntry::NewLC(aFullName, iConnFactoryL, aSettings, *iTimer);
       
   144 		TLinearOrder<CSqlCompactEntry> order(&CSqlCompactor::Compare);
       
   145 		__SQLLEAVE_IF_ERROR(iEntries.InsertInOrder(entry, order));
       
   146 		CleanupStack::Pop(entry);
       
   147 		}
       
   148 	else
       
   149 		{
       
   150 		entry = iEntries[idx];
       
   151 		__SQLASSERT(entry != NULL, ESqlPanicInternalError);
       
   152 		(void)entry->AddRef();
       
   153 		}
       
   154 	SQLCOMPACTOR_INVARIANT();
       
   155 	}
       
   156 
       
   157 /**
       
   158 Decrements the reference counter of the specified entry.
       
   159 If the counter reaches zero, the entry will be destroyed and removed form the container, the database connection - closed.
       
   160 
       
   161 @param aFullName The full database name, including the path.
       
   162 */
       
   163 void CSqlCompactor::ReleaseEntry(const TDesC& aFullName)
       
   164 	{
       
   165 	SQLCOMPACTOR_INVARIANT();
       
   166 	TInt idx = iEntries.FindInOrder(aFullName, &CSqlCompactor::Search);
       
   167 	__SQLASSERT(idx >= 0, ESqlPanicInternalError);
       
   168 	if(idx >= 0)
       
   169 		{
       
   170 		CSqlCompactEntry* entry = iEntries[idx];
       
   171 		__SQLASSERT(entry != NULL, ESqlPanicInternalError);
       
   172 		if(entry)
       
   173 			{
       
   174 			if(entry->Release() == 0)
       
   175 				{
       
   176 				iEntries.Remove(idx);
       
   177 				}
       
   178 			}
       
   179 		}
       
   180 	SQLCOMPACTOR_INVARIANT();
       
   181 	}
       
   182 
       
   183 /**
       
   184 Initializes the CSqlCompactor data members with their default values.
       
   185 
       
   186 @param aConnFactoryL MSqlCompactConn factory function.
       
   187 
       
   188 @panic SqlDb 4 In _DEBUG mode. NULL aConnFactoryL.
       
   189 */
       
   190 CSqlCompactor::CSqlCompactor(TSqlCompactConnFactoryL aConnFactoryL) :
       
   191 	iConnFactoryL(aConnFactoryL),
       
   192 	iEntries(KEntriesGranularity)
       
   193 	{
       
   194 	__SQLASSERT(aConnFactoryL != NULL, ESqlPanicBadArgument);
       
   195 	}
       
   196 
       
   197 /**
       
   198 Initializes the created CSqlCompactor instance.
       
   199 
       
   200 @param aCompactStepInterval The time interval between the background compaction steps.
       
   201 
       
   202 @panic SqlDb 4 In _DEBUG mode. Zero or negative aCompactStepInterval.
       
   203 */
       
   204 void CSqlCompactor::ConstructL(TInt aCompactStepInterval)
       
   205 	{
       
   206 	__SQLASSERT(aCompactStepInterval > 0, ESqlPanicBadArgument);
       
   207 	iTimer = CSqlCompactTimer::NewL(aCompactStepInterval);
       
   208 	}
       
   209 
       
   210 /**
       
   211 Static method used internally for performing a search in the container using database name as a key.
       
   212 
       
   213 @param aFullName The full database name, including the path.
       
   214 @param aEntry CSqlCompactor reference.
       
   215 */
       
   216 /* static */TInt CSqlCompactor::Search(const TDesC* aFullName, const CSqlCompactEntry& aEntry)
       
   217 	{
       
   218 	__SQLASSERT(&aEntry != NULL, ESqlPanicInternalError);
       
   219 	__SQLASSERT(aFullName != NULL, ESqlPanicInternalError);
       
   220 	const TDesC& fullName = *aFullName;
       
   221 	__SQLASSERT(fullName.Length() > 0 && fullName.Length() <= KMaxFileName, ESqlPanicInternalError);
       
   222 	__SQLASSERT(aEntry.FullName().Length() > 0 && aEntry.FullName().Length() <= KMaxFileName, ESqlPanicInternalError);
       
   223 	return fullName.CompareF(aEntry.FullName());
       
   224 	}
       
   225 
       
   226 /**
       
   227 Static method used internally for performing a search in the container using a CSqlCompactEntry reference as a key.
       
   228 */
       
   229 /* static */TInt CSqlCompactor::Compare(const CSqlCompactEntry& aLeft, const CSqlCompactEntry& aRight)
       
   230 	{
       
   231 	__SQLASSERT(&aLeft != NULL, ESqlPanicInternalError);
       
   232 	__SQLASSERT(&aRight != NULL, ESqlPanicInternalError);
       
   233 	__SQLASSERT(aLeft.FullName().Length() > 0 && aLeft.FullName().Length() <= KMaxFileName, ESqlPanicInternalError);
       
   234 	__SQLASSERT(aRight.FullName().Length() > 0 && aRight.FullName().Length() <= KMaxFileName, ESqlPanicInternalError);
       
   235 	return aLeft.FullName().CompareF(aRight.FullName());
       
   236 	}
       
   237 
       
   238 #ifdef _DEBUG
       
   239 /**
       
   240 CSqlCompactor invariant.
       
   241 */
       
   242 void CSqlCompactor::Invariant() const
       
   243 	{
       
   244 	__SQLASSERT(iConnFactoryL != NULL, ESqlPanicInternalError);
       
   245 	__SQLASSERT(iTimer != NULL, ESqlPanicInternalError);
       
   246 	iTimer->Invariant();
       
   247 	for(TInt idx=iEntries.Count()-1;idx>=0;--idx)
       
   248 		{
       
   249 		__SQLASSERT(iEntries[idx] != NULL, ESqlPanicInternalError);
       
   250 		iEntries[idx]->Invariant();
       
   251 		}
       
   252 	}
       
   253 #endif//_DEBUG