1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sql/SRC/Server/SqlSrvDriveSpace.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,267 @@
1.4 +// Copyright (c) 2004-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 +// Reserving/Accessing/Releasing drive space - CSqlDriveSpace and RSqlDriveSpaceCol classes implementations
1.18 +//
1.19 +//
1.20 +
1.21 +#include "SqlSrvDriveSpace.h"
1.22 +#include "SqlAssert.h"
1.23 +#include "OstTraceDefinitions.h"
1.24 +#ifdef OST_TRACE_COMPILER_IN_USE
1.25 +#include "SqlSrvDriveSpaceTraces.h"
1.26 +#endif
1.27 +#include "SqlTraceDef.h"
1.28 +
1.29 +/**
1.30 +The amount of the disk space, which will be reserved at the moment of creation of
1.31 +each CDriveSpace object.
1.32 +It should be enough for the most of "delete" transactions, if they do not require a rollback transaction
1.33 +file, bigger than KReservedDiskSpace bytes.
1.34 +
1.35 +Note: this is the max possible amount, which can be reserved per file session.
1.36 + Look for KMaxSessionDriveReserved constant value.
1.37 +
1.38 +@internalComponent
1.39 +*/
1.40 +const TInt KReservedDiskSpace = 64 * 1024;
1.41 +
1.42 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.43 +//////////////////////////////// CSqlDriveSpace class //////////////////////////////////////////////////////
1.44 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.45 +
1.46 +/**
1.47 +Standard phase-one factory method for creation of CSqlDriveSpace objects.
1.48 +
1.49 +@param aFs File session instance
1.50 +@param aDrive Drive number
1.51 +
1.52 +@return A pointer to the created CSqlDriveSpace object.
1.53 +
1.54 +@leave KErrNoMemory, Out of memory condition has occured;
1.55 + RFs::ReserveDriveSpace() return values.
1.56 +
1.57 +@panic SqlDb 4 In _DEBUG mode if aDrive is invalid
1.58 +
1.59 +@see RFs::ReserveDriveSpace()
1.60 +*/
1.61 +CSqlDriveSpace* CSqlDriveSpace::NewLC(RFs& aFs, TDriveNumber aDrive)
1.62 + {
1.63 + SQL_TRACE_INTERNALS(OstTraceExt2(TRACE_INTERNALS, CSQLDRIVESPACE_NEWLC_ENTRY, "Entry;0;CSqlDriveSpace::NewLC;aFs.Handle()=0x%X;aDrive=%d", (TUint)aFs.Handle(), (TInt)aDrive));
1.64 + __ASSERT_DEBUG(aDrive >= EDriveA && aDrive <= EDriveZ, __SQLPANIC2(ESqlPanicBadArgument));
1.65 + CSqlDriveSpace* self = new (ELeave) CSqlDriveSpace(aFs, aDrive);
1.66 + CleanupStack::PushL(self);
1.67 + self->ConstructL();
1.68 + SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLDRIVESPACE_NEWLC_EXIT, "Exit;0x%X;CSqlDriveSpace::NewLC", (TUint)self));
1.69 + return self;
1.70 + }
1.71 +
1.72 +/**
1.73 +Frees the reserved disk space.
1.74 +*/
1.75 +CSqlDriveSpace::~CSqlDriveSpace()
1.76 + {
1.77 + SQL_TRACE_INTERNALS(OstTraceExt3(TRACE_INTERNALS, CSQLDRIVESPACE_CSQLDRIVESPACE2, "0x%X;CSqlDriveSpace::~CSqlDriveSpace;iDrive=%d;iGetAccessRefCnt=%d", (TUint)this, (TInt)iDrive, iGetAccessRefCnt));
1.78 + SQLDRIVESPACE_INVARIANT();
1.79 + (void)iFs.ReleaseReserveAccess(static_cast <TInt> (iDrive));
1.80 + (void)iFs.ReserveDriveSpace(static_cast <TInt> (iDrive), 0);
1.81 + }
1.82 +
1.83 +/**
1.84 +Gives an access to the already reserved drive space. The method uses RFs::GetReserveAccess()
1.85 +for that. RFs::GetReserveAccess() will be called only once, when iGetAccessRefCnt is 0 -
1.86 +this is a shared file session instance.
1.87 +
1.88 +@leave RFs::GetReserveAccess() return values
1.89 +
1.90 +@see RFs::GetReserveAccess()
1.91 +
1.92 +@panic SqlDb 12 In _DEBUG mode if iGetAccessRefCnt < 0
1.93 +*/
1.94 +void CSqlDriveSpace::GetAccessL()
1.95 + {
1.96 + SQL_TRACE_INTERNALS(OstTraceExt3(TRACE_INTERNALS, CSQLDRIVESPACE_GETACCESSL_ENTRY, "Entry;0x%X;CSqlDriveSpace::GetAccessL;iDrive=%d;iGetAccessRefCnt=%d", (TUint)this, (TInt)iDrive, iGetAccessRefCnt));
1.97 + SQLDRIVESPACE_INVARIANT();
1.98 + //Gets an access only once, there is only one RFs session instance.
1.99 + if(iGetAccessRefCnt == 0)
1.100 + {
1.101 + __SQLLEAVE_IF_ERROR(iFs.GetReserveAccess(static_cast <TInt> (iDrive)));
1.102 + }
1.103 + ++iGetAccessRefCnt;
1.104 + SQL_TRACE_INTERNALS(OstTraceExt3(TRACE_INTERNALS, CSQLDRIVESPACE_GETACCESSL_EXIT, "Exit;0x%X;CSqlDriveSpace::GetAccessL;iDrive=%d;iGetAccessRefCnt=%d", (TUint)this, (TInt)iDrive, iGetAccessRefCnt));
1.105 + SQLDRIVESPACE_INVARIANT();
1.106 + }
1.107 +
1.108 +/**
1.109 +Revokes access to the reserved drive space.
1.110 +
1.111 +The method calls RFs::ReleaseReserveAccess() only when iGetAccessRefCnt value reaches 0.
1.112 +
1.113 +@see RFs::ReleaseReserveAccess()
1.114 +
1.115 +@panic SqlDb 12 In _DEBUG mode if iGetAccessRefCnt < 0
1.116 +*/
1.117 +void CSqlDriveSpace::ReleaseAccess()
1.118 + {
1.119 + SQL_TRACE_INTERNALS(OstTraceExt3(TRACE_INTERNALS, CSQLDRIVESPACE_RELEASEACCESS, "0x%X;CSqlDriveSpace::ReleaseAccess;iDrive=%d;iGetAccessRefCnt=%d", (TUint)this, (TInt)iDrive, iGetAccessRefCnt));
1.120 + SQLDRIVESPACE_INVARIANT();
1.121 + if(iGetAccessRefCnt == 0)
1.122 + {
1.123 + return;
1.124 + }
1.125 + if(--iGetAccessRefCnt == 0)
1.126 + {
1.127 + //I can't see any reason to bother the caller with errors, when the access to the
1.128 + //reserved space is revoked.
1.129 + (void)iFs.ReleaseReserveAccess(static_cast <TInt> (iDrive));
1.130 + }
1.131 + SQLDRIVESPACE_INVARIANT();
1.132 + }
1.133 +
1.134 +/**
1.135 +@param aFs File session instance
1.136 +@param aDrive Drive number
1.137 +
1.138 +@panic SqlDb 4 In _DEBUG mode if aDrive is invalid
1.139 +*/
1.140 +CSqlDriveSpace::CSqlDriveSpace(RFs& aFs, TDriveNumber aDrive) :
1.141 + iFs(aFs),
1.142 + iDrive(aDrive)
1.143 + {
1.144 + __ASSERT_DEBUG(aDrive >= EDriveA && aDrive <= EDriveZ, __SQLPANIC(ESqlPanicBadArgument));
1.145 + }
1.146 +
1.147 +/**
1.148 +Standard phase-two construction method for creation of CSqlDriveSpace objects.
1.149 +
1.150 +It will reserve a predefined amount of a disk space, enough for the most of the
1.151 +"delete" transactions, used by the applications.
1.152 +
1.153 +@leave RFs::ReserveDriveSpace() return values
1.154 +
1.155 +@see RFs::ReserveDriveSpace()
1.156 +*/
1.157 +void CSqlDriveSpace::ConstructL()
1.158 + {
1.159 + __SQLLEAVE_IF_ERROR(iFs.ReserveDriveSpace(static_cast <TInt> (iDrive), KReservedDiskSpace));
1.160 + SQLDRIVESPACE_INVARIANT();
1.161 + }
1.162 +
1.163 +#ifdef _DEBUG
1.164 +/**
1.165 +CSqlDriveSpace invariant.
1.166 +*/
1.167 +void CSqlDriveSpace::Invariant() const
1.168 + {
1.169 + __ASSERT_DEBUG(iDrive >= EDriveA && iDrive <= EDriveZ, __SQLPANIC(ESqlPanicInternalError));
1.170 + __ASSERT_DEBUG(iGetAccessRefCnt >= 0, __SQLPANIC(ESqlPanicMisuse));
1.171 + }
1.172 +#endif//_DEBUG
1.173 +
1.174 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.175 +//////////////////////////////// RSqlDriveSpaceCol class ///////////////////////////////////////////////////
1.176 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.177 +
1.178 +RSqlDriveSpaceCol::RSqlDriveSpaceCol() :
1.179 + iFs(NULL)
1.180 + {
1.181 + }
1.182 +
1.183 +/**
1.184 +@param aFs A reference to file session instance
1.185 +*/
1.186 +void RSqlDriveSpaceCol::Create(RFs& aFs)
1.187 + {
1.188 + iFs = &aFs;
1.189 + SQLDRIVESPACECOL_INVARIANT();
1.190 + }
1.191 +
1.192 +/**
1.193 +The method releases all the resources used by RSqlDriveSpaceCol object, including and
1.194 +reserved drive spaces on all drives in the collection.
1.195 +*/
1.196 +void RSqlDriveSpaceCol::ResetAndDestroy()
1.197 + {
1.198 + //Forced release of the reserved space
1.199 + for(TInt i=iDriveSpaceCol.Count()-1;i>=0;--i)
1.200 + {
1.201 + delete iDriveSpaceCol[i];
1.202 + }
1.203 + iDriveSpaceCol.Close();
1.204 + iFs = NULL;
1.205 + }
1.206 +
1.207 +/**
1.208 +Searches the collection for a CSqlDriveSpace object holding information about the reserved space on aDrive drive.
1.209 +
1.210 +@param aDrive Drive number.
1.211 +
1.212 +@return A pointer to the CSqlDriveSpace object, which handles drive space reservation requests
1.213 + for aDriveNo drive. If there is no such object, the method returns NULL.
1.214 +
1.215 +@panic SqlDb 4 In _DEBUG mode if aDrive is invalid
1.216 +*/
1.217 +CSqlDriveSpace* RSqlDriveSpaceCol::Find(TDriveNumber aDrive)
1.218 + {
1.219 + __ASSERT_DEBUG(aDrive >= EDriveA && aDrive <= EDriveZ, __SQLPANIC(ESqlPanicBadArgument));
1.220 + SQLDRIVESPACECOL_INVARIANT();
1.221 + for(TInt index=iDriveSpaceCol.Count()-1;index>=0;--index)
1.222 + {
1.223 + if(iDriveSpaceCol[index]->Drive() == aDrive)
1.224 + {
1.225 + return iDriveSpaceCol[index];
1.226 + }
1.227 + }
1.228 + SQLDRIVESPACECOL_INVARIANT();
1.229 + return NULL;
1.230 + }
1.231 +
1.232 +/**
1.233 +The method creates a new CSqlDriveSpace object, adds it to the collection and returns a pointer to it.
1.234 +
1.235 +@param aDrive Drive number.
1.236 +
1.237 +@return A pointer to the created CDriveSpace object, which handles drive space
1.238 + reservation requests for aDriveNo drive.
1.239 +
1.240 +@leave System-wide error codes, including KErrNoMemory.
1.241 +
1.242 +@panic SqlDb 4, In _DEBUG mode if aDrive is invalid.
1.243 +@panic SqlDb 12, In _DEBUG mode if a CDriveSpace object already exists for aDrive.
1.244 +*/
1.245 +CSqlDriveSpace* RSqlDriveSpaceCol::AddL(TDriveNumber aDrive)
1.246 + {
1.247 + __ASSERT_DEBUG(aDrive >= EDriveA && aDrive <= EDriveZ, __SQLPANIC(ESqlPanicBadArgument));
1.248 + __ASSERT_DEBUG(!Find(aDrive), __SQLPANIC(ESqlPanicMisuse));
1.249 + SQLDRIVESPACECOL_INVARIANT();
1.250 + CSqlDriveSpace* drvSpace = CSqlDriveSpace::NewLC(*iFs, aDrive);
1.251 + __SQLLEAVE_IF_ERROR(iDriveSpaceCol.Append(drvSpace));
1.252 + CleanupStack::Pop(drvSpace);
1.253 + SQLDRIVESPACECOL_INVARIANT();
1.254 + return drvSpace;
1.255 + }
1.256 +
1.257 +#ifdef _DEBUG
1.258 +/**
1.259 +RSqlDriveSpaceCol invariant.
1.260 +*/
1.261 +void RSqlDriveSpaceCol::Invariant() const
1.262 + {
1.263 + __ASSERT_DEBUG(iFs != NULL, __SQLPANIC(ESqlPanicInternalError));
1.264 + for(TInt index=iDriveSpaceCol.Count()-1;index>=0;--index)
1.265 + {
1.266 + iDriveSpaceCol[index]->Invariant();
1.267 + }
1.268 + }
1.269 +#endif//_DEBUG
1.270 +