--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/sql/SRC/Server/Compact/SqlCompact.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,253 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "SqlPanic.h"
+#include "SqlCompact.h"
+#include "SqlCompactEntry.h"
+#include "SqlCompactTimer.h"
+#include "SqlUtil.h"
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+Initializes the background compaction stettings with their default values.
+*/
+TSqlCompactSettings::TSqlCompactSettings() :
+ iStepLength(KSqlCompactStepLengthMs),
+ iFreePageThresholdKb(KSqlCompactFreePageThresholdKb)
+ {
+ }
+
+#ifdef _DEBUG
+/**
+CSqlCompactSettings invariant.
+*/
+void TSqlCompactSettings::Invariant() const
+ {
+ __SQLASSERT(iStepLength > 0, ESqlPanicInternalError);
+ __SQLASSERT(iFreePageThresholdKb >= 0, ESqlPanicInternalError);
+ }
+#endif//_DEBUG
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+The granularity of the container maintained by CSqlCompactor
+
+@see CSqlCompactor
+@internalComponent
+*/
+const TInt KEntriesGranularity = 16;
+
+/**
+Creates a new CSqlCompactor instance.
+
+@param aConnFactoryL MSqlCompactConn factory function.
+@param aCompactStepInterval The time intrerval (ms) between the background compaction steps.
+
+@return A pointer to the created CSqlCompactor instance
+
+@leave KErrNoMemory, an out of memory condition has occurred;
+ Note that the function may also leave with some other database specific
+ errors categorised as ESqlDbError, and other system-wide error codes.
+
+@panic SqlDb 4 In _DEBUG mode. NULL aConnFactoryL.
+@panic SqlDb 4 In _DEBUG mode. Zero or negative aCompactStepInterval.
+*/
+CSqlCompactor* CSqlCompactor::NewL(TSqlCompactConnFactoryL aConnFactoryL, TInt aCompactStepInterval)
+ {
+ __SQLASSERT(aConnFactoryL != NULL, ESqlPanicBadArgument);
+ __SQLASSERT(aCompactStepInterval > 0, ESqlPanicBadArgument);
+ CSqlCompactor* self = new (ELeave) CSqlCompactor(aConnFactoryL);
+ CleanupStack::PushL(self);
+ self->ConstructL(aCompactStepInterval);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+Destroys the CSqlCompactor instance.
+Any entries left in the container will be destroyed.
+*/
+CSqlCompactor::~CSqlCompactor()
+ {
+ for(TInt idx=iEntries.Count()-1;idx>=0;--idx)
+ {
+ __SQLASSERT(iEntries[idx] != NULL, ESqlPanicInternalError);
+ while(iEntries[idx]->Release() != 0)
+ {
+ }
+ }
+ iEntries.Close();
+ delete iTimer;
+ }
+
+/**
+Restarts the background compaction timer.
+This function should be called from the server side session object's ServiceL().
+If ServiceL() is being executed at the moment, it is very likely that the SQL client(s) will issue another
+request few ms later. In order to not delay the processing of the client(s) requests, ServiceL() should call
+at the end RestartTimer(). If there are database entries scheduled for a background compaction, the compaction
+will be delayed by the time interval used by the CSqlCompactTimer object (default value - KSqlCompactStepInterval).
+
+@see CSqlCompactTimer
+@see KSqlCompactStepInterval
+*/
+void CSqlCompactor::RestartTimer()
+ {
+ SQLCOMPACTOR_INVARIANT();
+ iTimer->Restart();
+ SQLCOMPACTOR_INVARIANT();
+ }
+
+/**
+If an entry referring to a database with name aFullName does not exist in the container, a new entry will be created,
+a connection with the database established.
+If an entry with the specidfied name already exists, no new entry wil be created, the reference counter of the existing one
+will be incremented.
+
+@param aFullName The full database name, including the path.
+@param aSettings Per-database background compaction settings
+
+@leave KErrNoMemory, an out of memory condition has occurred;
+ Note that the function may also leave with some other database specific
+ errors categorised as ESqlDbError, and other system-wide error codes.
+
+@panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
+@panic SqlDb 7 In _DEBUG mode. An entry with the specidfied name has been found but the entry is NULL.
+*/
+void CSqlCompactor::AddEntryL(const TDesC& aFullName, const TSqlCompactSettings& aSettings)
+ {
+ __SQLASSERT(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, ESqlPanicBadArgument);
+ SQLCOMPACTOR_INVARIANT();
+ CSqlCompactEntry* entry = NULL;
+ TInt idx = iEntries.FindInOrder(aFullName, &CSqlCompactor::Search);
+ if(idx == KErrNotFound)
+ {
+ entry = CSqlCompactEntry::NewLC(aFullName, iConnFactoryL, aSettings, *iTimer);
+ TLinearOrder<CSqlCompactEntry> order(&CSqlCompactor::Compare);
+ __SQLLEAVE_IF_ERROR(iEntries.InsertInOrder(entry, order));
+ CleanupStack::Pop(entry);
+ }
+ else
+ {
+ entry = iEntries[idx];
+ __SQLASSERT(entry != NULL, ESqlPanicInternalError);
+ (void)entry->AddRef();
+ }
+ SQLCOMPACTOR_INVARIANT();
+ }
+
+/**
+Decrements the reference counter of the specified entry.
+If the counter reaches zero, the entry will be destroyed and removed form the container, the database connection - closed.
+
+@param aFullName The full database name, including the path.
+*/
+void CSqlCompactor::ReleaseEntry(const TDesC& aFullName)
+ {
+ SQLCOMPACTOR_INVARIANT();
+ TInt idx = iEntries.FindInOrder(aFullName, &CSqlCompactor::Search);
+ __SQLASSERT(idx >= 0, ESqlPanicInternalError);
+ if(idx >= 0)
+ {
+ CSqlCompactEntry* entry = iEntries[idx];
+ __SQLASSERT(entry != NULL, ESqlPanicInternalError);
+ if(entry)
+ {
+ if(entry->Release() == 0)
+ {
+ iEntries.Remove(idx);
+ }
+ }
+ }
+ SQLCOMPACTOR_INVARIANT();
+ }
+
+/**
+Initializes the CSqlCompactor data members with their default values.
+
+@param aConnFactoryL MSqlCompactConn factory function.
+
+@panic SqlDb 4 In _DEBUG mode. NULL aConnFactoryL.
+*/
+CSqlCompactor::CSqlCompactor(TSqlCompactConnFactoryL aConnFactoryL) :
+ iConnFactoryL(aConnFactoryL),
+ iEntries(KEntriesGranularity)
+ {
+ __SQLASSERT(aConnFactoryL != NULL, ESqlPanicBadArgument);
+ }
+
+/**
+Initializes the created CSqlCompactor instance.
+
+@param aCompactStepInterval The time interval between the background compaction steps.
+
+@panic SqlDb 4 In _DEBUG mode. Zero or negative aCompactStepInterval.
+*/
+void CSqlCompactor::ConstructL(TInt aCompactStepInterval)
+ {
+ __SQLASSERT(aCompactStepInterval > 0, ESqlPanicBadArgument);
+ iTimer = CSqlCompactTimer::NewL(aCompactStepInterval);
+ }
+
+/**
+Static method used internally for performing a search in the container using database name as a key.
+
+@param aFullName The full database name, including the path.
+@param aEntry CSqlCompactor reference.
+*/
+/* static */TInt CSqlCompactor::Search(const TDesC* aFullName, const CSqlCompactEntry& aEntry)
+ {
+ __SQLASSERT(&aEntry != NULL, ESqlPanicInternalError);
+ __SQLASSERT(aFullName != NULL, ESqlPanicInternalError);
+ const TDesC& fullName = *aFullName;
+ __SQLASSERT(fullName.Length() > 0 && fullName.Length() <= KMaxFileName, ESqlPanicInternalError);
+ __SQLASSERT(aEntry.FullName().Length() > 0 && aEntry.FullName().Length() <= KMaxFileName, ESqlPanicInternalError);
+ return fullName.CompareF(aEntry.FullName());
+ }
+
+/**
+Static method used internally for performing a search in the container using a CSqlCompactEntry reference as a key.
+*/
+/* static */TInt CSqlCompactor::Compare(const CSqlCompactEntry& aLeft, const CSqlCompactEntry& aRight)
+ {
+ __SQLASSERT(&aLeft != NULL, ESqlPanicInternalError);
+ __SQLASSERT(&aRight != NULL, ESqlPanicInternalError);
+ __SQLASSERT(aLeft.FullName().Length() > 0 && aLeft.FullName().Length() <= KMaxFileName, ESqlPanicInternalError);
+ __SQLASSERT(aRight.FullName().Length() > 0 && aRight.FullName().Length() <= KMaxFileName, ESqlPanicInternalError);
+ return aLeft.FullName().CompareF(aRight.FullName());
+ }
+
+#ifdef _DEBUG
+/**
+CSqlCompactor invariant.
+*/
+void CSqlCompactor::Invariant() const
+ {
+ __SQLASSERT(iConnFactoryL != NULL, ESqlPanicInternalError);
+ __SQLASSERT(iTimer != NULL, ESqlPanicInternalError);
+ iTimer->Invariant();
+ for(TInt idx=iEntries.Count()-1;idx>=0;--idx)
+ {
+ __SQLASSERT(iEntries[idx] != NULL, ESqlPanicInternalError);
+ iEntries[idx]->Invariant();
+ }
+ }
+#endif//_DEBUG