diff -r 000000000000 -r 08ec8eefde2f persistentstorage/dbms/utable/UT_WIN.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/dbms/utable/UT_WIN.CPP Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,337 @@ +// Copyright (c) 1998-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 "UT_STD.H" + +// Class CDbBasicWindowStage + +CDbBasicWindowStage::CDbBasicWindowStage(const TDbWindow& aWindow) + : iWindow(aWindow), iRecords(EWindowArrayGranularity), iPos(-1) + { + __ASSERT(aWindow.Size()!=aWindow.ENone); + } + +TBool CDbBasicWindowStage::GetRecord(TDbRecordId& aRecordId) + { + if (TUint(iPos)>=TUint(iRecords.Count())) + return EFalse; + aRecordId=iRecords[iPos]; + return ETrue; + } + +void CDbBasicWindowStage::Reset() +// +// Reset the window to initial state +// + { + CDbDataStage::Reset(); + iRecords.Reset(); + iPos=-1; + } + +TBool CDbBasicWindowStage::EvaluateL(TInt& aWork,TDbRecordId& aRecordId,TBool& aAtRow) +// +// Do as much work as we can to make the window match the desired shape +// + { + TBool eval=CDbDataStage::EvaluateL(aWork,aRecordId,aAtRow); + if (!eval) + { + eval=DoEvaluateL(aWork); + aAtRow=GetRecord(aRecordId); + } + return eval; + } + +TInt CDbBasicWindowStage::CountL() +// +// Window'd views only report the evaluated records +// + { + return iRecords.Count(); + } + +CDbBasicWindowStage::TGoto CDbBasicWindowStage::GotoL(TInt& /*aWork*/,TDbPosition aPosition,TDbRecordId& aRecordId) + { + switch (aPosition) + { + default: + __ASSERT(0); + break; + case EDbFirst: + iPos=0; + break; + case EDbLast: + iPos=iRecords.Count()-1; + break; + case EDbNext: + ++iPos; + break; + case EDbPrevious: + --iPos; + break; + } + return GetRecord(aRecordId) ? ESuccess : ENoRow; + } + +TInt CDbBasicWindowStage::Find(TDbRecordId aRecordId,TInt& aPos) + { + TKeyArrayFix key(0,ECmpTUint32); + return iRecords.Find(aRecordId,key,aPos); + } + +TBool CDbBasicWindowStage::GotoL(TDbRecordId aRecordId) + { + return Find(aRecordId,iPos)==0; + } + +void CDbBasicWindowStage::ReadRowL(TDbRecordId aRecordId) + { + TRAPD(r,CDbDataStage::ReadRowL(aRecordId)); + if (r==KErrNotFound) + { + TInt pos; + if (Find(aRecordId,pos)==KErrNone) + { + iRecords.Delete(pos); + if (pos0 at end. 0 none +// + { + if (iView==EAll) + return 0; + if (iWindow.Size()==iWindow.EUnlimited) + return KMaxTInt; + TInt space=iWindow.Size()-iRecords.Count(); + TInt lag=iPos-iWindow.PreferredPos(); + switch (iView) + { + default: + __ASSERT(0); + case EBeginning: + return space+Max(lag,0); // fill up and use forward lag if any + case EEnd: + return Min(lag,0)-space; // fill up backwards and use rear lag if any + case EMiddle: + if (lag<0 && iIterPos==EAtBeginning) // use iterator position if we can + return lag; + if (space+lag>0) + return space+lag; + if (lag<0) + return lag; + return 0; + } + } + +TDbPosition CDbWindowStage::ResetIterToBeginningL() + { + for (TInt ii=iRecords.Count();--ii>=0;) + { + if (CDbDataStage::GotoL(iRecords[0])) + return EDbPrevious; +// has been deleted, try the next one + iRecords.Delete(0); + if (iPos>0) + --iPos; + } +// no records to work with, start at the end + return EDbLast; + } + +TDbPosition CDbWindowStage::ResetIterToEndL() + { + for (TInt ii=iRecords.Count();--ii>=0;) + { + if (CDbDataStage::GotoL(iRecords[ii])) + return EDbNext; +// has been deleted, try the next one + iRecords.Delete(ii); + if (iPos>ii) + --iPos; + } +// no records to work with, start at the beginning + return EDbFirst; + } + +TDbPosition CDbWindowStage::SetIteratorL(TInt anEval) +// +// Set the iterator for some work and return the first iterator direction +// + { + switch (iIterPos) + { + default: + __ASSERT(0); + case EAtBeginning: + if (anEval<0) + return EDbPrevious; +// turn around iterator to work at end + iIterPos=EAtEnd; + return ResetIterToEndL(); + case EAtEnd: + if (anEval>0) + return EDbNext; +// turn around iterator to work at beginning + iIterPos=EAtBeginning; + return ResetIterToBeginningL(); + } + } + +void CDbWindowStage::ExtendAtBeginningL(TInt aRecords,TDbPosition aFirst,TInt& aWork) + { + TDbRecordId id=iRecords.Count()>0 ? iRecords[0] : KDbNullRecordId; + while (aRecords>0) + { + switch (CDbDataStage::GotoL(aWork,aFirst,id)) + { + default: + __ASSERT(0); + case EExhausted: + return; + case ESuccess: + if (iRecords.Count()==iWindow.Size()) + { // drop last record + iRecords.Delete(iRecords.Count()-1); + if (iView==EEnd) + iView=EMiddle; + } + iRecords.InsertL(0,id); + ++iPos; + if (aFirst==EDbLast) + aFirst=EDbPrevious; + --aRecords; + break; + case ENoRow: // no more data that way + iView=iView==EEnd ? EAll : EBeginning; + return; + case ESynchFailure: // have to do some work on the iterator now + aFirst=ResetIterToBeginningL(); + break; + } + } + } + +void CDbWindowStage::ExtendAtEndL(TInt aRecords,TDbPosition aFirst,TInt& aWork) + { + TDbRecordId id=iRecords.Count()>0 ? iRecords[iRecords.Count()-1] : KDbNullRecordId; + while (aRecords>0) + { + switch (CDbDataStage::GotoL(aWork,aFirst,id)) + { + default: + __ASSERT(0); + case EExhausted: + return; + case ESuccess: + if (iRecords.Count()==iWindow.Size()) + { // drop first record + iRecords.Delete(0); + --iPos; + if (iView==EBeginning) + iView=EMiddle; + } + iRecords.AppendL(id); + if (aFirst==EDbFirst) + aFirst=EDbNext; + --aRecords; + break; + case ENoRow: + iView=iView==EBeginning ? EAll : EEnd; + return; + case ESynchFailure: + aFirst=ResetIterToEndL(); + break; + } + } + } + +TBool CDbWindowStage::DoEvaluateL(TInt& aWork) +// +// Do as much work as we can to make the window match the desired shape +// + { + for (;;) + { + TInt eval=WhatToEvaluate(); + if (eval==0) + return EFalse; + if (aWork<=0) + return ETrue; + TDbPosition dir=SetIteratorL(eval); + if (eval>0) + ExtendAtEndL(eval,dir,aWork); + else + ExtendAtBeginningL(-eval,dir,aWork); + } + } + +TBool CDbWindowStage::Unevaluated() +// +// Return whether it is worth Evaluating +// + { + return WhatToEvaluate()==0 ? CDbDataStage::Unevaluated() : ETrue; + }