os/persistentdata/persistentstorage/dbms/utable/UT_WIN.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "UT_STD.H"
sl@0
    17
sl@0
    18
// Class CDbBasicWindowStage
sl@0
    19
sl@0
    20
CDbBasicWindowStage::CDbBasicWindowStage(const TDbWindow& aWindow)
sl@0
    21
	: iWindow(aWindow), iRecords(EWindowArrayGranularity), iPos(-1)
sl@0
    22
	{
sl@0
    23
	__ASSERT(aWindow.Size()!=aWindow.ENone);
sl@0
    24
	}
sl@0
    25
sl@0
    26
TBool CDbBasicWindowStage::GetRecord(TDbRecordId& aRecordId)
sl@0
    27
	{
sl@0
    28
	if (TUint(iPos)>=TUint(iRecords.Count()))
sl@0
    29
		return EFalse;
sl@0
    30
	aRecordId=iRecords[iPos];
sl@0
    31
	return ETrue;
sl@0
    32
	}
sl@0
    33
sl@0
    34
void CDbBasicWindowStage::Reset()
sl@0
    35
//
sl@0
    36
// Reset the window to initial state
sl@0
    37
//
sl@0
    38
	{
sl@0
    39
	CDbDataStage::Reset();
sl@0
    40
	iRecords.Reset();
sl@0
    41
	iPos=-1;
sl@0
    42
	}
sl@0
    43
sl@0
    44
TBool CDbBasicWindowStage::EvaluateL(TInt& aWork,TDbRecordId& aRecordId,TBool& aAtRow)
sl@0
    45
//
sl@0
    46
// Do as much work as we can to make the window match the desired shape
sl@0
    47
//
sl@0
    48
	{
sl@0
    49
	TBool eval=CDbDataStage::EvaluateL(aWork,aRecordId,aAtRow);
sl@0
    50
	if (!eval)
sl@0
    51
		{
sl@0
    52
		eval=DoEvaluateL(aWork);
sl@0
    53
		aAtRow=GetRecord(aRecordId);
sl@0
    54
		}
sl@0
    55
	return eval;
sl@0
    56
	}
sl@0
    57
sl@0
    58
TInt CDbBasicWindowStage::CountL()
sl@0
    59
//
sl@0
    60
// Window'd views only report the evaluated records
sl@0
    61
//
sl@0
    62
	{
sl@0
    63
	return iRecords.Count();
sl@0
    64
	}
sl@0
    65
sl@0
    66
CDbBasicWindowStage::TGoto CDbBasicWindowStage::GotoL(TInt& /*aWork*/,TDbPosition aPosition,TDbRecordId& aRecordId)
sl@0
    67
	{
sl@0
    68
	switch (aPosition)
sl@0
    69
		{
sl@0
    70
	default:
sl@0
    71
		__ASSERT(0);
sl@0
    72
		break;
sl@0
    73
	case EDbFirst:
sl@0
    74
		iPos=0;
sl@0
    75
		break;
sl@0
    76
	case EDbLast:
sl@0
    77
		iPos=iRecords.Count()-1;
sl@0
    78
		break;
sl@0
    79
	case EDbNext:
sl@0
    80
		++iPos;
sl@0
    81
		break;
sl@0
    82
	case EDbPrevious:
sl@0
    83
		--iPos;
sl@0
    84
		break;
sl@0
    85
		}
sl@0
    86
	return GetRecord(aRecordId) ? ESuccess : ENoRow;
sl@0
    87
	}
sl@0
    88
sl@0
    89
TInt CDbBasicWindowStage::Find(TDbRecordId aRecordId,TInt& aPos)
sl@0
    90
	{
sl@0
    91
	TKeyArrayFix key(0,ECmpTUint32);
sl@0
    92
	return iRecords.Find(aRecordId,key,aPos);
sl@0
    93
	}
sl@0
    94
sl@0
    95
TBool CDbBasicWindowStage::GotoL(TDbRecordId aRecordId)
sl@0
    96
	{
sl@0
    97
	return Find(aRecordId,iPos)==0;
sl@0
    98
	}
sl@0
    99
sl@0
   100
void CDbBasicWindowStage::ReadRowL(TDbRecordId aRecordId)
sl@0
   101
	{
sl@0
   102
	TRAPD(r,CDbDataStage::ReadRowL(aRecordId));
sl@0
   103
	if (r==KErrNotFound)
sl@0
   104
		{
sl@0
   105
		TInt pos;
sl@0
   106
		if (Find(aRecordId,pos)==KErrNone)
sl@0
   107
			{
sl@0
   108
			iRecords.Delete(pos);
sl@0
   109
			if (pos<iPos)
sl@0
   110
				--iPos;
sl@0
   111
			}
sl@0
   112
		}
sl@0
   113
	__LEAVE_IF_ERROR(r);
sl@0
   114
	}
sl@0
   115
sl@0
   116
TDbRecordId CDbBasicWindowStage::WriteRowL(TWrite aWrite,TSynch aSynch)
sl@0
   117
	{
sl@0
   118
	TDbRecordId id=CDbDataStage::WriteRowL(aWrite,ENoSynch);
sl@0
   119
	if (aWrite==EAppend && iWindow.Size()==iWindow.EUnlimited)
sl@0
   120
		{
sl@0
   121
		iRecords.AppendL(id);
sl@0
   122
		if (aSynch==ESynch)
sl@0
   123
			iPos=iRecords.Count()-1;	// follow the append
sl@0
   124
		}
sl@0
   125
	return id;
sl@0
   126
	}
sl@0
   127
sl@0
   128
CDbBasicWindowStage::TDelete CDbBasicWindowStage::DeleteRowL(TDbRecordId& aRecordId,TSynch)
sl@0
   129
//
sl@0
   130
// Remove the row from the window if it is present
sl@0
   131
//
sl@0
   132
	{
sl@0
   133
	CDbDataStage::DeleteRowL(aRecordId,ENoSynch);
sl@0
   134
	if (GotoL(aRecordId))
sl@0
   135
		{
sl@0
   136
		iRecords.Delete(iPos);
sl@0
   137
		if (GetRecord(aRecordId))
sl@0
   138
			return EDeletedAtNext;
sl@0
   139
		}
sl@0
   140
	return EDeletedAtEnd;
sl@0
   141
	}
sl@0
   142
sl@0
   143
// Class CDbWindowStage
sl@0
   144
sl@0
   145
CDbWindowStage::CDbWindowStage(const TDbWindow& aWindow)
sl@0
   146
	: CDbBasicWindowStage(aWindow), iIterPos(EAtBeginning), iView(EBeginning)
sl@0
   147
	{}
sl@0
   148
sl@0
   149
void CDbWindowStage::Reset()
sl@0
   150
//
sl@0
   151
// Reset the window to initial state
sl@0
   152
//
sl@0
   153
	{
sl@0
   154
	CDbBasicWindowStage::Reset();
sl@0
   155
	iIterPos=EAtBeginning;
sl@0
   156
	iView=EBeginning;
sl@0
   157
	}
sl@0
   158
sl@0
   159
TInt CDbWindowStage::WhatToEvaluate()
sl@0
   160
//
sl@0
   161
// count of slots to fill, <0 at beginning, >0 at end. 0 none
sl@0
   162
//
sl@0
   163
	{
sl@0
   164
	if (iView==EAll)
sl@0
   165
		return 0;
sl@0
   166
	if (iWindow.Size()==iWindow.EUnlimited)
sl@0
   167
		return KMaxTInt;
sl@0
   168
	TInt space=iWindow.Size()-iRecords.Count();
sl@0
   169
	TInt lag=iPos-iWindow.PreferredPos();
sl@0
   170
	switch (iView)
sl@0
   171
		{
sl@0
   172
	default:
sl@0
   173
		__ASSERT(0);
sl@0
   174
	case EBeginning:
sl@0
   175
		return space+Max(lag,0);	// fill up and use forward lag if any
sl@0
   176
	case EEnd:
sl@0
   177
		return Min(lag,0)-space;	// fill up backwards and use rear lag if any
sl@0
   178
	case EMiddle:
sl@0
   179
		if (lag<0 && iIterPos==EAtBeginning)	// use iterator position if we can
sl@0
   180
			return lag;
sl@0
   181
		if (space+lag>0)
sl@0
   182
			return space+lag;
sl@0
   183
		if (lag<0)
sl@0
   184
			return lag;
sl@0
   185
		return 0;
sl@0
   186
		}
sl@0
   187
	}
sl@0
   188
sl@0
   189
TDbPosition CDbWindowStage::ResetIterToBeginningL()
sl@0
   190
	{
sl@0
   191
	for (TInt ii=iRecords.Count();--ii>=0;)
sl@0
   192
		{
sl@0
   193
		if (CDbDataStage::GotoL(iRecords[0]))
sl@0
   194
			return EDbPrevious;
sl@0
   195
// has been deleted, try the next one
sl@0
   196
		iRecords.Delete(0);
sl@0
   197
		if (iPos>0)
sl@0
   198
			--iPos;
sl@0
   199
		}
sl@0
   200
// no records to work with, start at the end
sl@0
   201
	return EDbLast;
sl@0
   202
	}
sl@0
   203
sl@0
   204
TDbPosition CDbWindowStage::ResetIterToEndL()
sl@0
   205
	{
sl@0
   206
	for (TInt ii=iRecords.Count();--ii>=0;)
sl@0
   207
		{
sl@0
   208
		if (CDbDataStage::GotoL(iRecords[ii]))
sl@0
   209
			return EDbNext;
sl@0
   210
// has been deleted, try the next one
sl@0
   211
		iRecords.Delete(ii);
sl@0
   212
		if (iPos>ii)
sl@0
   213
			--iPos;
sl@0
   214
		}
sl@0
   215
// no records to work with, start at the beginning
sl@0
   216
	return EDbFirst;
sl@0
   217
	}
sl@0
   218
sl@0
   219
TDbPosition CDbWindowStage::SetIteratorL(TInt anEval)
sl@0
   220
//
sl@0
   221
// Set the iterator for some work and return the first iterator direction
sl@0
   222
//
sl@0
   223
	{
sl@0
   224
	switch (iIterPos)
sl@0
   225
		{
sl@0
   226
	default:
sl@0
   227
		__ASSERT(0);
sl@0
   228
	case EAtBeginning:
sl@0
   229
		if (anEval<0)
sl@0
   230
			return EDbPrevious;
sl@0
   231
// turn around iterator to work at end
sl@0
   232
		iIterPos=EAtEnd;
sl@0
   233
		return ResetIterToEndL();
sl@0
   234
	case EAtEnd:
sl@0
   235
		if (anEval>0)
sl@0
   236
			return EDbNext;
sl@0
   237
// turn around iterator to work at beginning
sl@0
   238
		iIterPos=EAtBeginning;
sl@0
   239
		return ResetIterToBeginningL();
sl@0
   240
		}
sl@0
   241
	}
sl@0
   242
sl@0
   243
void CDbWindowStage::ExtendAtBeginningL(TInt aRecords,TDbPosition aFirst,TInt& aWork)
sl@0
   244
	{
sl@0
   245
	TDbRecordId id=iRecords.Count()>0 ? iRecords[0] : KDbNullRecordId;
sl@0
   246
	while (aRecords>0)
sl@0
   247
		{
sl@0
   248
		switch (CDbDataStage::GotoL(aWork,aFirst,id))
sl@0
   249
			{
sl@0
   250
		default:
sl@0
   251
			__ASSERT(0);
sl@0
   252
		case EExhausted:
sl@0
   253
			return;
sl@0
   254
		case ESuccess:
sl@0
   255
			if (iRecords.Count()==iWindow.Size())
sl@0
   256
				{	// drop last record
sl@0
   257
				iRecords.Delete(iRecords.Count()-1);
sl@0
   258
				if (iView==EEnd)
sl@0
   259
					iView=EMiddle;
sl@0
   260
				}
sl@0
   261
			iRecords.InsertL(0,id);
sl@0
   262
			++iPos;
sl@0
   263
			if (aFirst==EDbLast)
sl@0
   264
				aFirst=EDbPrevious;
sl@0
   265
			--aRecords;
sl@0
   266
			break;
sl@0
   267
		case ENoRow:	// no more data that way
sl@0
   268
			iView=iView==EEnd ? EAll : EBeginning;
sl@0
   269
			return;
sl@0
   270
		case ESynchFailure:	// have to do some work on the iterator now
sl@0
   271
			aFirst=ResetIterToBeginningL();
sl@0
   272
			break;
sl@0
   273
			}
sl@0
   274
		}
sl@0
   275
	}
sl@0
   276
sl@0
   277
void CDbWindowStage::ExtendAtEndL(TInt aRecords,TDbPosition aFirst,TInt& aWork)
sl@0
   278
	{
sl@0
   279
	TDbRecordId id=iRecords.Count()>0 ? iRecords[iRecords.Count()-1] : KDbNullRecordId;
sl@0
   280
	while (aRecords>0)
sl@0
   281
		{
sl@0
   282
		switch (CDbDataStage::GotoL(aWork,aFirst,id))
sl@0
   283
			{
sl@0
   284
		default:
sl@0
   285
			__ASSERT(0);
sl@0
   286
		case EExhausted:
sl@0
   287
			return;
sl@0
   288
		case ESuccess:
sl@0
   289
			if (iRecords.Count()==iWindow.Size())
sl@0
   290
				{	// drop first record
sl@0
   291
				iRecords.Delete(0);
sl@0
   292
				--iPos;
sl@0
   293
				if (iView==EBeginning)
sl@0
   294
					iView=EMiddle;
sl@0
   295
				}
sl@0
   296
			iRecords.AppendL(id);
sl@0
   297
			if (aFirst==EDbFirst)
sl@0
   298
				aFirst=EDbNext;
sl@0
   299
			--aRecords;
sl@0
   300
			break;
sl@0
   301
		case ENoRow:
sl@0
   302
			iView=iView==EBeginning ? EAll : EEnd;
sl@0
   303
			return;
sl@0
   304
		case ESynchFailure:
sl@0
   305
			aFirst=ResetIterToEndL();
sl@0
   306
			break;
sl@0
   307
			}
sl@0
   308
		}
sl@0
   309
	}
sl@0
   310
sl@0
   311
TBool CDbWindowStage::DoEvaluateL(TInt& aWork)
sl@0
   312
//
sl@0
   313
// Do as much work as we can to make the window match the desired shape
sl@0
   314
//
sl@0
   315
	{
sl@0
   316
	for (;;)
sl@0
   317
		{
sl@0
   318
		TInt eval=WhatToEvaluate();
sl@0
   319
		if (eval==0)
sl@0
   320
			return EFalse;
sl@0
   321
		if (aWork<=0)
sl@0
   322
			return ETrue;
sl@0
   323
		TDbPosition dir=SetIteratorL(eval);
sl@0
   324
		if (eval>0)
sl@0
   325
			ExtendAtEndL(eval,dir,aWork);
sl@0
   326
		else
sl@0
   327
			ExtendAtBeginningL(-eval,dir,aWork);
sl@0
   328
		}
sl@0
   329
	}
sl@0
   330
sl@0
   331
TBool CDbWindowStage::Unevaluated()
sl@0
   332
//
sl@0
   333
// Return whether it is worth Evaluating
sl@0
   334
//
sl@0
   335
	{
sl@0
   336
	return WhatToEvaluate()==0 ? CDbDataStage::Unevaluated() : ETrue;
sl@0
   337
	}