os/persistentdata/persistentstorage/sql/SRC/Server/Compact/SqlCompact.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sql/SRC/Server/Compact/SqlCompact.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,269 @@
     1.4 +// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "SqlAssert.h"
    1.20 +#include "SqlCompact.h"
    1.21 +#include "SqlCompactEntry.h"
    1.22 +#include "SqlCompactTimer.h"
    1.23 +#include "SqlUtil.h"
    1.24 +#include "OstTraceDefinitions.h"
    1.25 +#ifdef OST_TRACE_COMPILER_IN_USE
    1.26 +#include "SqlCompactTraces.h"
    1.27 +#endif
    1.28 +#include "SqlTraceDef.h"
    1.29 +
    1.30 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.31 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.32 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.33 +
    1.34 +/**
    1.35 +Initializes the background compaction settings with their default values.
    1.36 +*/
    1.37 +TSqlCompactSettings::TSqlCompactSettings() :
    1.38 +	iStepLength(KSqlCompactStepLengthMs),
    1.39 +	iFreePageThresholdKb(KSqlCompactFreePageThresholdKb)
    1.40 +	{
    1.41 +	}
    1.42 +
    1.43 +#ifdef _DEBUG
    1.44 +/**
    1.45 +CSqlCompactSettings invariant.
    1.46 +*/
    1.47 +void TSqlCompactSettings::Invariant() const
    1.48 +	{
    1.49 +	__ASSERT_DEBUG(iStepLength > 0, __SQLPANIC(ESqlPanicInternalError));
    1.50 +	__ASSERT_DEBUG(iFreePageThresholdKb >= 0, __SQLPANIC(ESqlPanicInternalError));
    1.51 +	}
    1.52 +#endif//_DEBUG
    1.53 +
    1.54 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.55 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.56 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.57 +
    1.58 +/**
    1.59 +The granularity of the container maintained by CSqlCompactor
    1.60 +
    1.61 +@see CSqlCompactor
    1.62 +@internalComponent
    1.63 +*/
    1.64 +const TInt KEntriesGranularity = 16;
    1.65 +
    1.66 +/**
    1.67 +Creates a new CSqlCompactor instance.
    1.68 +
    1.69 +@param aConnFactoryL MSqlCompactConn factory function.
    1.70 +@param aCompactStepInterval The time interval (ms) between the background compaction steps.
    1.71 +
    1.72 +@return A pointer to the created CSqlCompactor instance
    1.73 +
    1.74 +@leave KErrNoMemory, an out of memory condition has occurred;
    1.75 +                     Note that the function may also leave with some other database specific 
    1.76 +                     errors categorised as ESqlDbError, and other system-wide error codes.
    1.77 +
    1.78 +@panic SqlDb 4 In _DEBUG mode. NULL aConnFactoryL.
    1.79 +@panic SqlDb 4 In _DEBUG mode. Zero or negative aCompactStepInterval.
    1.80 +*/
    1.81 +CSqlCompactor* CSqlCompactor::NewL(TSqlCompactConnFactoryL aConnFactoryL, TInt aCompactStepInterval)
    1.82 +	{
    1.83 +	__ASSERT_DEBUG(aConnFactoryL != NULL, __SQLPANIC2(ESqlPanicBadArgument));
    1.84 +	__ASSERT_DEBUG(aCompactStepInterval > 0, __SQLPANIC2(ESqlPanicBadArgument));
    1.85 +	CSqlCompactor* self = new (ELeave) CSqlCompactor(aConnFactoryL);
    1.86 +	CleanupStack::PushL(self);
    1.87 +	self->ConstructL(aCompactStepInterval);
    1.88 +	CleanupStack::Pop(self);
    1.89 +	return self;
    1.90 +	}
    1.91 +
    1.92 +/**
    1.93 +Destroys the CSqlCompactor instance. 
    1.94 +Any entries left in the container will be destroyed.
    1.95 +*/
    1.96 +CSqlCompactor::~CSqlCompactor()
    1.97 +	{
    1.98 +	for(TInt idx=iEntries.Count()-1;idx>=0;--idx)
    1.99 +		{
   1.100 +		__ASSERT_DEBUG(iEntries[idx] != NULL, __SQLPANIC(ESqlPanicInternalError));
   1.101 +		while(iEntries[idx]->Release() != 0)
   1.102 +			{
   1.103 +			}
   1.104 +		}
   1.105 +	iEntries.Close();
   1.106 +	delete iTimer;
   1.107 +	}
   1.108 +
   1.109 +/**
   1.110 +Restarts the background compaction timer. 
   1.111 +This function should be called from the server side session object's ServiceL(). 
   1.112 +If ServiceL() is being executed at the moment, it is very likely that the SQL client(s) will issue another
   1.113 +request few ms later. In order to not delay the processing of the client(s) requests, ServiceL() should call
   1.114 +at the end RestartTimer(). If there are database entries scheduled for a background compaction, the compaction
   1.115 +will be delayed by the time interval used by the CSqlCompactTimer object (default value - KSqlCompactStepInterval).
   1.116 +
   1.117 +@see CSqlCompactTimer
   1.118 +@see KSqlCompactStepInterval
   1.119 +*/
   1.120 +void CSqlCompactor::RestartTimer()
   1.121 +	{
   1.122 +	SQLCOMPACTOR_INVARIANT();
   1.123 +	iTimer->Restart();
   1.124 +	SQLCOMPACTOR_INVARIANT();
   1.125 +	}
   1.126 +
   1.127 +/**
   1.128 +If an entry referring to a database with name aFullName does not exist in the container, a new entry will be created,
   1.129 +a connection with the database established.
   1.130 +If an entry with the specified name already exists, no new entry wil be created, the reference counter of the existing one 
   1.131 +will be incremented.
   1.132 +
   1.133 +@param aFullName The full database name, including the path.
   1.134 +@param aSettings Per-database background compaction settings
   1.135 +
   1.136 +@leave KErrNoMemory, an out of memory condition has occurred;
   1.137 +                     Note that the function may also leave with some other database specific 
   1.138 +                     errors categorised as ESqlDbError, and other system-wide error codes.
   1.139 +
   1.140 +@panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
   1.141 +@panic SqlDb 7 In _DEBUG mode. An entry with the specified name has been found but the entry is NULL.
   1.142 +*/
   1.143 +void CSqlCompactor::AddEntryL(const TDesC& aFullName, const TSqlCompactSettings& aSettings)
   1.144 +	{
   1.145 +	__ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC(ESqlPanicBadArgument));
   1.146 +	SQLCOMPACTOR_INVARIANT();
   1.147 +	CSqlCompactEntry* entry = NULL;
   1.148 +	TInt idx = iEntries.FindInOrder(aFullName, &CSqlCompactor::Search);
   1.149 +	if(idx == KErrNotFound)
   1.150 +		{
   1.151 +		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));
   1.152 +		entry = CSqlCompactEntry::NewLC(aFullName, iConnFactoryL, aSettings, *iTimer);
   1.153 +		TLinearOrder<CSqlCompactEntry> order(&CSqlCompactor::Compare);
   1.154 +		__SQLLEAVE_IF_ERROR(iEntries.InsertInOrder(entry, order));
   1.155 +		CleanupStack::Pop(entry);
   1.156 +		}
   1.157 +	else
   1.158 +		{
   1.159 +		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));
   1.160 +		entry = iEntries[idx];
   1.161 +		__ASSERT_DEBUG(entry != NULL, __SQLPANIC(ESqlPanicInternalError));
   1.162 +		(void)entry->AddRef();
   1.163 +		}
   1.164 +	SQLCOMPACTOR_INVARIANT();
   1.165 +	}
   1.166 +
   1.167 +/**
   1.168 +Decrements the reference counter of the specified entry.
   1.169 +If the counter reaches zero, the entry will be destroyed and removed from the container, 
   1.170 +the database connection - closed.
   1.171 +
   1.172 +@param aFullName The full database name, including the path.
   1.173 +*/
   1.174 +void CSqlCompactor::ReleaseEntry(const TDesC& aFullName)
   1.175 +	{
   1.176 +	SQL_TRACE_COMPACT(OstTraceExt2(TRACE_INTERNALS, CSQLCOMPACTOR_RELEASEENTRY1, "0x%X;CSqlCompactor::ReleaseEntry;aFullName=%S", (TUint)this, __SQLPRNSTR(aFullName)));
   1.177 +	SQLCOMPACTOR_INVARIANT();
   1.178 +	TInt idx = iEntries.FindInOrder(aFullName, &CSqlCompactor::Search);
   1.179 +	__ASSERT_DEBUG(idx >= 0, __SQLPANIC(ESqlPanicInternalError));
   1.180 +	if(idx >= 0)
   1.181 +		{
   1.182 +		CSqlCompactEntry* entry = iEntries[idx];
   1.183 +		__ASSERT_DEBUG(entry != NULL, __SQLPANIC(ESqlPanicInternalError));
   1.184 +		if(entry)
   1.185 +			{
   1.186 +			if(entry->Release() == 0)
   1.187 +				{
   1.188 +				iEntries.Remove(idx);			
   1.189 +#ifdef _DEBUG
   1.190 +//This is used prevent the failure of the resource allocation checking for debug mode. 
   1.191 +				if(iEntries.Count() == 0)
   1.192 +				    {
   1.193 +                    iEntries.Reset();
   1.194 +				    }
   1.195 +#endif  
   1.196 +				}
   1.197 +			}
   1.198 +		}
   1.199 +	SQLCOMPACTOR_INVARIANT();
   1.200 +	}
   1.201 +
   1.202 +/**
   1.203 +Initializes the CSqlCompactor data members with their default values.
   1.204 +
   1.205 +@param aConnFactoryL MSqlCompactConn factory function.
   1.206 +
   1.207 +@panic SqlDb 4 In _DEBUG mode. NULL aConnFactoryL.
   1.208 +*/
   1.209 +CSqlCompactor::CSqlCompactor(TSqlCompactConnFactoryL aConnFactoryL) :
   1.210 +	iConnFactoryL(aConnFactoryL),
   1.211 +	iEntries(KEntriesGranularity)
   1.212 +	{
   1.213 +	__ASSERT_DEBUG(aConnFactoryL != NULL, __SQLPANIC(ESqlPanicBadArgument));
   1.214 +	}
   1.215 +
   1.216 +/**
   1.217 +Initializes the created CSqlCompactor instance.
   1.218 +
   1.219 +@param aCompactStepInterval The time interval between the background compaction steps.
   1.220 +
   1.221 +@panic SqlDb 4 In _DEBUG mode. Zero or negative aCompactStepInterval.
   1.222 +*/
   1.223 +void CSqlCompactor::ConstructL(TInt aCompactStepInterval)
   1.224 +	{
   1.225 +	__ASSERT_DEBUG(aCompactStepInterval > 0, __SQLPANIC(ESqlPanicBadArgument));
   1.226 +	iTimer = CSqlCompactTimer::NewL(aCompactStepInterval);
   1.227 +	}
   1.228 +
   1.229 +/**
   1.230 +Static method used internally for performing a search in the container using database name as a key.
   1.231 +
   1.232 +@param aFullName The full database name, including the path.
   1.233 +@param aEntry CSqlCompactor reference.
   1.234 +*/
   1.235 +/* static */TInt CSqlCompactor::Search(const TDesC* aFullName, const CSqlCompactEntry& aEntry)
   1.236 +	{
   1.237 +	__ASSERT_DEBUG(&aEntry != NULL, __SQLPANIC2(ESqlPanicInternalError));
   1.238 +	__ASSERT_DEBUG(aFullName != NULL, __SQLPANIC2(ESqlPanicInternalError));
   1.239 +	const TDesC& fullName = *aFullName;
   1.240 +	__ASSERT_DEBUG(fullName.Length() > 0 && fullName.Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicInternalError));
   1.241 +	__ASSERT_DEBUG(aEntry.FullName().Length() > 0 && aEntry.FullName().Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicInternalError));
   1.242 +	return fullName.CompareF(aEntry.FullName());
   1.243 +	}
   1.244 +
   1.245 +/**
   1.246 +Static method used internally for performing a search in the container using a CSqlCompactEntry reference as a key.
   1.247 +*/
   1.248 +/* static */TInt CSqlCompactor::Compare(const CSqlCompactEntry& aLeft, const CSqlCompactEntry& aRight)
   1.249 +	{
   1.250 +	__ASSERT_DEBUG(&aLeft != NULL, __SQLPANIC2(ESqlPanicInternalError));
   1.251 +	__ASSERT_DEBUG(&aRight != NULL, __SQLPANIC2(ESqlPanicInternalError));
   1.252 +	__ASSERT_DEBUG(aLeft.FullName().Length() > 0 && aLeft.FullName().Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicInternalError));
   1.253 +	__ASSERT_DEBUG(aRight.FullName().Length() > 0 && aRight.FullName().Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicInternalError));
   1.254 +	return aLeft.FullName().CompareF(aRight.FullName());
   1.255 +	}
   1.256 +
   1.257 +#ifdef _DEBUG
   1.258 +/**
   1.259 +CSqlCompactor invariant.
   1.260 +*/
   1.261 +void CSqlCompactor::Invariant() const
   1.262 +	{
   1.263 +	__ASSERT_DEBUG(iConnFactoryL != NULL, __SQLPANIC(ESqlPanicInternalError));
   1.264 +	__ASSERT_DEBUG(iTimer != NULL, __SQLPANIC(ESqlPanicInternalError));
   1.265 +	iTimer->Invariant();
   1.266 +	for(TInt idx=iEntries.Count()-1;idx>=0;--idx)
   1.267 +		{
   1.268 +		__ASSERT_DEBUG(iEntries[idx] != NULL, __SQLPANIC(ESqlPanicInternalError));
   1.269 +		iEntries[idx]->Invariant();
   1.270 +		}
   1.271 +	}
   1.272 +#endif//_DEBUG