| branch | GCC_SURGE |
| changeset 38 | c4e342fcf0c8 |
| parent 35 | 0d6db0a14001 |
| child 41 | 3256212fc81f |
| 27:ba32e40d9f36 | 38:c4e342fcf0c8 |
|---|---|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
1 // Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
2 // All rights reserved. |
2 // All rights reserved. |
3 // This component and the accompanying materials are made available |
3 // This component and the accompanying materials are made available |
4 // under the terms of "Eclipse Public License v1.0" |
4 // under the terms of "Eclipse Public License v1.0" |
5 // which accompanies this distribution, and is available |
5 // which accompanies this distribution, and is available |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
20 |
20 |
21 #ifdef _SQLPROFILER |
21 #ifdef _SQLPROFILER |
22 |
22 |
23 extern TBool TheOsCallTimeDetailedProfileEnabled;//If true, the OS porting layer call details are enabled and for each call an entry will be added to the log file (epocwind.out). |
23 extern TBool TheOsCallTimeDetailedProfileEnabled;//If true, the OS porting layer call details are enabled and for each call an entry will be added to the log file (epocwind.out). |
24 |
24 |
25 #define PROFILE_READ(pos,amount) \ |
25 #define PROFILE_READ(pos, amount, err) \ |
26 do \ |
26 do \ |
27 { \ |
27 { \ |
28 if(TheOsCallTimeDetailedProfileEnabled) \ |
28 if(TheOsCallTimeDetailedProfileEnabled) \ |
29 { \ |
29 { \ |
30 ++iFileReadCount; iFileReadAmount += (amount); \ |
30 ++iFileReadCount; iFileReadAmount += (amount); \ |
31 RDebug::Print(_L(" -- FRead this=%X, Cnt=%d, Pos=%ld, Amt=%d, Ttl=%ld\r\n"), (TUint32)this, iFileReadCount, pos, amount, iFileReadAmount); \ |
31 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Read¬%d¬%ld¬%d¬%ld¬%d\r\n"), (TUint32)this, iFileReadCount, pos, amount, iFileReadAmount, err); \ |
32 } \ |
32 } \ |
33 } while(0) |
33 } while(0) |
34 |
34 |
35 #define PROFILE_WRITE(pos,amount) \ |
35 #define PROFILE_WRITE(pos, amount, err) \ |
36 do \ |
36 do \ |
37 { \ |
37 { \ |
38 if(TheOsCallTimeDetailedProfileEnabled) \ |
38 if(TheOsCallTimeDetailedProfileEnabled) \ |
39 { \ |
39 { \ |
40 ++iFileWriteCount; iFileWriteAmount += (amount); \ |
40 ++iFileWriteCount; iFileWriteAmount += (amount); \ |
41 RDebug::Print(_L(" -- FWrite this=%X, Cnt=%d, Pos=%ld, Amt=%d, Ttl=%ld\r\n"), (TUint32)this, iFileWriteCount, pos, amount, iFileWriteAmount); \ |
41 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Write¬%d¬%ld¬%d¬%ld¬%d\r\n"), (TUint32)this, iFileWriteCount, pos, amount, iFileWriteAmount, err); \ |
42 } \ |
42 } \ |
43 } while(0) |
43 } while(0) |
44 |
44 |
45 #define PROFILE_SIZE() \ |
45 #define PROFILE_SIZE(size, err) \ |
46 do \ |
46 do \ |
47 { \ |
47 { \ |
48 if(TheOsCallTimeDetailedProfileEnabled) \ |
48 if(TheOsCallTimeDetailedProfileEnabled) \ |
49 { \ |
49 { \ |
50 ++iFileSizeCount; \ |
50 ++iFileSizeCount; \ |
51 RDebug::Print(_L(" -- FSize this=%X, Cnt=%d\r\n"), (TUint32)this, iFileSizeCount); \ |
51 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Size¬%d¬%ld¬¬¬%d\r\n"), (TUint32)this, iFileSizeCount, size, err); \ |
52 } \ |
52 } \ |
53 } while(0) |
53 } while(0) |
54 |
54 |
55 #define PROFILE_SETSIZE() \ |
55 #define PROFILE_SETSIZE(size, err) \ |
56 do \ |
56 do \ |
57 { \ |
57 { \ |
58 if(TheOsCallTimeDetailedProfileEnabled) \ |
58 if(TheOsCallTimeDetailedProfileEnabled) \ |
59 { \ |
59 { \ |
60 ++iFileSetSizeCount; \ |
60 ++iFileSetSizeCount; \ |
61 RDebug::Print(_L(" -- FSetSize this=%X, Cnt=%d\r\n"), (TUint32)this, iFileSetSizeCount); \ |
61 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬SetSize¬%d¬%ld¬¬¬%d\r\n"), (TUint32)this, iFileSetSizeCount, size, err); \ |
62 } \ |
62 } \ |
63 } while(0) |
63 } while(0) |
64 |
64 |
65 #define PROFILE_FLUSH() \ |
65 #define PROFILE_FLUSH(err) \ |
66 do \ |
66 do \ |
67 { \ |
67 { \ |
68 if(TheOsCallTimeDetailedProfileEnabled) \ |
68 if(TheOsCallTimeDetailedProfileEnabled) \ |
69 { \ |
69 { \ |
70 ++iFileFlushCount; \ |
70 ++iFileFlushCount; \ |
71 RDebug::Print(_L(" -- FFlush this=%X, Cnt=%d\r\n"), (TUint32)this, iFileFlushCount); \ |
71 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Flush¬%d¬¬¬¬%d\r\n"), (TUint32)this, iFileFlushCount, err); \ |
72 } \ |
72 } \ |
73 } while(0) |
73 } while(0) |
74 |
74 |
75 #define PROFILE_CREATE(fname, err) \ |
|
76 do \ |
|
77 { \ |
|
78 if(TheOsCallTimeDetailedProfileEnabled) \ |
|
79 { \ |
|
80 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Create¬¬¬¬¬%d¬%S\r\n"), (TUint32)this, err, &fname); \ |
|
81 } \ |
|
82 } while(0) |
|
83 |
|
84 #define PROFILE_OPEN(fname, err) \ |
|
85 do \ |
|
86 { \ |
|
87 if(TheOsCallTimeDetailedProfileEnabled) \ |
|
88 { \ |
|
89 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Open¬¬¬¬¬%d¬%S\r\n"), (TUint32)this, err, &fname); \ |
|
90 } \ |
|
91 } while(0) |
|
92 |
|
93 #define PROFILE_TEMP(fname, err) \ |
|
94 do \ |
|
95 { \ |
|
96 if(TheOsCallTimeDetailedProfileEnabled) \ |
|
97 { \ |
|
98 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Temp¬¬¬¬¬%d¬%S\r\n"), (TUint32)this, err, &fname); \ |
|
99 } \ |
|
100 } while(0) |
|
101 |
|
102 #define PROFILE_ADOPT(fname, err) \ |
|
103 do \ |
|
104 { \ |
|
105 if(TheOsCallTimeDetailedProfileEnabled) \ |
|
106 { \ |
|
107 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Adopt¬¬¬¬¬%d¬%S\r\n"), (TUint32)this, err, &fname); \ |
|
108 } \ |
|
109 } while(0) |
|
110 |
|
111 #define PROFILE_CLOSE() \ |
|
112 do \ |
|
113 { \ |
|
114 if(TheOsCallTimeDetailedProfileEnabled) \ |
|
115 { \ |
|
116 RDebug::Print(_L("[SQL-FBUF]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬Close¬¬¬¬¬¬\r\n"), (TUint32)this); \ |
|
117 } \ |
|
118 } while(0) |
|
119 |
|
75 //Resets the profiler counters |
120 //Resets the profiler counters |
76 void RFileBuf64::ProfilerReset() |
121 void RFileBuf64::ProfilerReset() |
77 { |
122 { |
78 iFileReadCount = 0; iFileReadAmount = 0; iFileWriteCount = 0; iFileWriteAmount = 0; iFileSizeCount = 0; iFileSetSizeCount = 0; iFileFlushCount = 0; |
123 iFileReadCount = 0; iFileReadAmount = 0; iFileWriteCount = 0; iFileWriteAmount = 0; iFileSizeCount = 0; iFileSetSizeCount = 0; iFileFlushCount = 0; |
79 } |
124 } |
80 |
125 |
81 #else |
126 #else |
82 |
127 |
83 #define PROFILE_READ(pos,amount) void(0) |
128 #define PROFILE_READ(pos,amount, err) void(0) |
84 #define PROFILE_WRITE(pos,amount) void(0) |
129 #define PROFILE_WRITE(pos,amount, err) void(0) |
85 |
130 |
86 #define PROFILE_SIZE() void(0) |
131 #define PROFILE_SIZE(size, err) void(0) |
87 #define PROFILE_SETSIZE() void(0) |
132 #define PROFILE_SETSIZE(size, err) void(0) |
88 #define PROFILE_FLUSH() void(0) |
133 #define PROFILE_FLUSH(err) void(0) |
134 |
|
135 #define PROFILE_CREATE(fname, err) void(0) |
|
136 #define PROFILE_OPEN(fname, err) void(0) |
|
137 #define PROFILE_TEMP(fname, err) void(0) |
|
138 #define PROFILE_ADOPT(fname, err) void(0) |
|
139 #define PROFILE_CLOSE() void(0) |
|
89 |
140 |
90 #endif//_SQLPROFILER |
141 #endif//_SQLPROFILER |
91 |
142 |
92 /** |
143 /** |
93 This constant is used for initializing the RFileBuf64::iFileSize data member and means that |
144 This constant is used for initializing the RFileBuf64::iFileSize data member and means that |
142 EFBufPanicNullThis, |
193 EFBufPanicNullThis, |
143 EFBufPanicDirty, |
194 EFBufPanicDirty, |
144 EFBufPanicNextReadFilePos, |
195 EFBufPanicNextReadFilePos, |
145 EFBufPanicNextReadFilePosHits, |
196 EFBufPanicNextReadFilePosHits, |
146 EFBufPanicFileBlockSize, //15 |
197 EFBufPanicFileBlockSize, //15 |
198 EFBufPanicRwDataLength, |
|
147 }; |
199 }; |
148 |
200 |
149 /** |
201 /** |
150 Helper function used in the implementation of the __FBUF64_ASSERT() macro. |
202 Helper function used in the implementation of the __FBUF64_ASSERT() macro. |
151 In case if the expression in __FBUF64_ASSERT() macro evaluates to false, |
203 In case if the expression in __FBUF64_ASSERT() macro evaluates to false, |
196 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
248 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
197 |
249 |
198 /** |
250 /** |
199 Initializes RFileBuf64 data members with their default values. |
251 Initializes RFileBuf64 data members with their default values. |
200 |
252 |
201 @param aSize Max file buffer size (capacity) in bytes. |
253 @param aMinCapacity Minimal file buffer size (capacity) in bytes. |
202 |
254 |
203 @panic FBuf64 1 In _DEBUG mode - aSize is 0 or negative. |
255 @panic FBuf64 1 In _DEBUG mode - aMinCapacity is 0 or negative. |
204 */ |
256 */ |
205 RFileBuf64::RFileBuf64(TInt aSize) : |
257 RFileBuf64::RFileBuf64(TInt aMinCapacity) : |
206 iCapacity(aSize), |
258 iCapacity(aMinCapacity), |
207 iReadAheadSize(RFileBuf64::KDefaultReadAheadSize) |
259 iReadAheadSize(RFileBuf64::KDefaultReadAheadSize), |
208 { |
260 iOptimized(EFalse) |
209 __FBUF64_ASSERT(aSize > 0, EFBufPanicCapacity); |
261 { |
262 __FBUF64_ASSERT(aMinCapacity > 0, EFBufPanicCapacity); |
|
210 } |
263 } |
211 |
264 |
212 /** |
265 /** |
213 Initializes the RFileBuf64 object and creates and opens a new file that will be accessed through RFileBuf64 public interface. |
266 Initializes the RFileBuf64 object and creates and opens a new file that will be accessed through RFileBuf64 public interface. |
214 If the file already exists, an error is returned. |
267 If the file already exists, an error is returned. |
236 TInt err = DoPreInit(); |
289 TInt err = DoPreInit(); |
237 if(err == KErrNone) |
290 if(err == KErrNone) |
238 { |
291 { |
239 err = iFile.Create(aFs, aFileName, aFileMode); |
292 err = iFile.Create(aFs, aFileName, aFileMode); |
240 } |
293 } |
294 PROFILE_CREATE(aFileName, err); |
|
241 return DoPostInit(err); |
295 return DoPostInit(err); |
242 } |
296 } |
243 |
297 |
244 /** |
298 /** |
245 Initializes the RFileBuf64 object and opens an existing file that will be accessed through RFileBuf64 public interface. |
299 Initializes the RFileBuf64 object and opens an existing file that will be accessed through RFileBuf64 public interface. |
267 TInt err = DoPreInit(); |
321 TInt err = DoPreInit(); |
268 if(err == KErrNone) |
322 if(err == KErrNone) |
269 { |
323 { |
270 err = iFile.Open(aFs, aFileName, aFileMode); |
324 err = iFile.Open(aFs, aFileName, aFileMode); |
271 } |
325 } |
326 PROFILE_OPEN(aFileName, err); |
|
272 return DoPostInit(err); |
327 return DoPostInit(err); |
273 } |
328 } |
274 |
329 |
275 /** |
330 /** |
276 Initializes the RFileBuf64 object and creates and opens a temporary file with unique name that will be accessed through |
331 Initializes the RFileBuf64 object and creates and opens a temporary file with unique name that will be accessed through |
298 TInt err = DoPreInit(); |
353 TInt err = DoPreInit(); |
299 if(err == KErrNone) |
354 if(err == KErrNone) |
300 { |
355 { |
301 err = iFile.Temp(aFs, aPath, aFileName, aFileMode); |
356 err = iFile.Temp(aFs, aPath, aFileName, aFileMode); |
302 } |
357 } |
358 PROFILE_TEMP(aFileName, err); |
|
303 return DoPostInit(err); |
359 return DoPostInit(err); |
304 } |
360 } |
305 |
361 |
306 /** |
362 /** |
307 Initializes the RFileBuf64 object and creates and adopts an already open file from a client that will be accessed through |
363 Initializes the RFileBuf64 object and creates and adopts an already open file from a client that will be accessed through |
334 TInt err = DoPreInit(); |
390 TInt err = DoPreInit(); |
335 if(err == KErrNone) |
391 if(err == KErrNone) |
336 { |
392 { |
337 err = iFile.AdoptFromClient(aMsg, aFsIndex, aFileIndex); |
393 err = iFile.AdoptFromClient(aMsg, aFsIndex, aFileIndex); |
338 } |
394 } |
395 PROFILE_ADOPT(KNullDesC, err); |
|
339 return DoPostInit(err); |
396 return DoPostInit(err); |
340 } |
397 } |
341 |
398 |
342 /** |
399 /** |
343 Writes to the file the pending data (if the buffer contains pending data), closes the file and releases |
400 Writes to the file the pending data (if the buffer contains pending data), closes the file and releases |
354 (void)DoFileWrite2(); |
411 (void)DoFileWrite2(); |
355 } |
412 } |
356 iFile.Close(); |
413 iFile.Close(); |
357 User::Free(iBase); |
414 User::Free(iBase); |
358 iBase = 0; |
415 iBase = 0; |
416 PROFILE_CLOSE(); |
|
359 } |
417 } |
360 |
418 |
361 /** |
419 /** |
362 Calculates and sets optimal read-ahead buffer size. |
420 Calculates and sets optimal read-ahead buffer size. |
363 aBlockSize and aReadRecBufSize values are retrieved by the caller from the file system. |
421 aBlockSize and aReadRecBufSize values are retrieved by the caller from the file system. |
415 TInt RFileBuf64::Read(TInt64 aFilePos, TDes8& aDes) |
473 TInt RFileBuf64::Read(TInt64 aFilePos, TDes8& aDes) |
416 { |
474 { |
417 __FBUF64_ASSERT(aFilePos >= 0, EFBufPanicFilePos); |
475 __FBUF64_ASSERT(aFilePos >= 0, EFBufPanicFilePos); |
418 __FILEBUF64_INVARIANT(); |
476 __FILEBUF64_INVARIANT(); |
419 aDes.SetLength(0); |
477 aDes.SetLength(0); |
420 //1. The output buffer max len is 0 |
478 //0. The output buffer max len is 0 |
421 if(aDes.MaxLength() == 0) |
479 if(aDes.MaxLength() == 0) |
422 { |
480 { |
423 __FILEBUF64_INVARIANT(); |
481 __FILEBUF64_INVARIANT(); |
424 return KErrNone; |
482 return KErrNone; |
425 } |
483 } |
426 //2. Initialize the "iFileSize" if it is not initialized yet |
484 //1. Initialize the "iFileSize" if it is not initialized yet |
427 TInt err = DoFileSize(); |
485 TInt err = DoFileSize(); |
428 if(err != KErrNone) |
486 if(err != KErrNone) |
429 { |
487 { |
430 __FILEBUF64_INVARIANT(); |
488 __FILEBUF64_INVARIANT(); |
431 return err; |
489 return err; |
432 } |
490 } |
491 //2. Optimize the buffer capacity |
|
492 TInt len = aDes.MaxLength(); |
|
493 if((err = DoSetCapacity(len)) != KErrNone) |
|
494 { |
|
495 return err; |
|
496 } |
|
433 //3. Too big "read" request - read directly from the file |
497 //3. Too big "read" request - read directly from the file |
434 TInt len = aDes.MaxLength(); |
|
435 if(len > iCapacity) |
498 if(len > iCapacity) |
436 { |
499 { |
437 if((aFilePos + len) > iFilePos && aFilePos < (iFilePos + iLength)) |
500 if((aFilePos + len) > iFilePos && aFilePos < (iFilePos + iLength)) |
438 {//Write the pending data if the iDirty flag is set, otherwise preserve the buffer content. |
501 {//Write the pending data if the iDirty flag is set, otherwise preserve the buffer content. |
439 err = DoFileWrite1(aFilePos); |
502 err = DoFileWrite1(aFilePos); |
440 } |
503 } |
441 if(err == KErrNone) |
504 if(err == KErrNone) |
442 { |
505 { |
443 err = iFile.Read(aFilePos, aDes); |
506 err = iFile.Read(aFilePos, aDes); |
444 PROFILE_READ(aFilePos, aDes.Size()); |
507 PROFILE_READ(aFilePos, aDes.Size(), err); |
445 } |
508 } |
446 __FILEBUF64_INVARIANT(); |
509 __FILEBUF64_INVARIANT(); |
447 return err; |
510 return err; |
448 } |
511 } |
449 //4. The requested data size is smaller than the buffer capacity |
512 //4. The requested data size is smaller than the buffer capacity |
470 if(iNextReadFilePos != aFilePos) |
533 if(iNextReadFilePos != aFilePos) |
471 {//Guessed read ahead was wrong. Direct "file read" operation |
534 {//Guessed read ahead was wrong. Direct "file read" operation |
472 iNextReadFilePosHits = 0; |
535 iNextReadFilePosHits = 0; |
473 TPtr8 ptr2(outptr, len); |
536 TPtr8 ptr2(outptr, len); |
474 err = iFile.Read(aFilePos, ptr2); |
537 err = iFile.Read(aFilePos, ptr2); |
475 PROFILE_READ(aFilePos, ptr2.Size()); |
538 PROFILE_READ(aFilePos, ptr2.Size(), err); |
476 if(err == KErrNone) |
539 if(err == KErrNone) |
477 { |
540 { |
478 iNextReadFilePos = aFilePos + len; |
541 iNextReadFilePos = aFilePos + len; |
479 len -= ptr2.Length(); |
542 len -= ptr2.Length(); |
480 } |
543 } |
481 break; |
544 break; |
482 } |
545 } |
483 //The guessed from the previous "file read" operation file pos is correct. Start reading-ahead. |
546 //The guessed from the previous "file read" operation file pos is correct. Start reading-ahead. |
484 const TInt KMaxReadFilePosHits = 8;//The max read-ahead buffer size can be up to 2^8 times the iReadAheadSize |
547 const TInt KMaxReadFilePosHits = 4;//The max read-ahead buffer size can be up to 2^4 times the iReadAheadSize |
485 if(iNextReadFilePosHits < KMaxReadFilePosHits) |
548 if(iNextReadFilePosHits < KMaxReadFilePosHits) |
486 { |
549 { |
487 ++iNextReadFilePosHits; |
550 ++iNextReadFilePosHits; |
488 } |
551 } |
489 TInt maxReadAhead = iReadAheadSize * (1 << iNextReadFilePosHits); |
552 TInt maxReadAhead = iReadAheadSize * (1 << iNextReadFilePosHits); |
494 // if read-ahead doesn't cross block boundary do it all |
557 // if read-ahead doesn't cross block boundary do it all |
495 readahead = maxReadAhead; |
558 readahead = maxReadAhead; |
496 } |
559 } |
497 TPtr8 ptr(iBase, Min(iCapacity, (len + readahead))); |
560 TPtr8 ptr(iBase, Min(iCapacity, (len + readahead))); |
498 err = iFile.Read(aFilePos, ptr); |
561 err = iFile.Read(aFilePos, ptr); |
499 PROFILE_READ(aFilePos, ptr.Size()); |
562 PROFILE_READ(aFilePos, ptr.Size(), err); |
500 if(err == KErrNone) |
563 if(err == KErrNone) |
501 { |
564 { |
502 iFilePos = aFilePos; |
565 iFilePos = aFilePos; |
503 iLength = ptr.Length(); |
566 iLength = ptr.Length(); |
504 iNextReadFilePos = iFilePos + iLength; |
567 iNextReadFilePos = iFilePos + iLength; |
549 TInt err = DoFileSize(); |
612 TInt err = DoFileSize(); |
550 if(err != KErrNone) |
613 if(err != KErrNone) |
551 { |
614 { |
552 __FILEBUF64_INVARIANT(); |
615 __FILEBUF64_INVARIANT(); |
553 return err; |
616 return err; |
617 } |
|
618 if((err = DoSetCapacity(aData.Length())) != KErrNone) |
|
619 { |
|
620 return err; |
|
554 } |
621 } |
555 DoDiscardBufferedReadData(); |
622 DoDiscardBufferedReadData(); |
556 const TUint8* data = aData.Ptr(); |
623 const TUint8* data = aData.Ptr(); |
557 for(TInt len = aData.Length(); len > 0 && err == KErrNone;) |
624 for(TInt len = aData.Length(); len > 0 && err == KErrNone;) |
558 { |
625 { |
785 if(iFileSize != KFileSizeNotSet) |
852 if(iFileSize != KFileSizeNotSet) |
786 { |
853 { |
787 __FILEBUF64_INVARIANT(); |
854 __FILEBUF64_INVARIANT(); |
788 return KErrNone; |
855 return KErrNone; |
789 } |
856 } |
790 PROFILE_SIZE(); |
|
791 TInt err = iFile.Size(iFileSize); |
857 TInt err = iFile.Size(iFileSize); |
858 PROFILE_SIZE(iFileSize, err); |
|
792 if(err != KErrNone) |
859 if(err != KErrNone) |
793 { |
860 { |
794 DoDiscard(); |
861 DoDiscard(); |
795 } |
862 } |
796 __FILEBUF64_INVARIANT(); |
863 __FILEBUF64_INVARIANT(); |
823 //If the new file size is "in" the buffer then change the "iLength" |
890 //If the new file size is "in" the buffer then change the "iLength" |
824 else if(aFileSize < (iFilePos + iLength)) |
891 else if(aFileSize < (iFilePos + iLength)) |
825 { |
892 { |
826 iLength = aFileSize - iFilePos; |
893 iLength = aFileSize - iFilePos; |
827 } |
894 } |
828 PROFILE_SETSIZE(); |
|
829 TInt err = iFile.SetSize(aFileSize); |
895 TInt err = iFile.SetSize(aFileSize); |
896 PROFILE_SETSIZE(aFileSize, err); |
|
830 if(err != KErrNone) |
897 if(err != KErrNone) |
831 { |
898 { |
832 DoDiscard(); |
899 DoDiscard(); |
833 } |
900 } |
834 else |
901 else |
855 if(err != KErrNone) |
922 if(err != KErrNone) |
856 { |
923 { |
857 __FILEBUF64_INVARIANT(); |
924 __FILEBUF64_INVARIANT(); |
858 return err; |
925 return err; |
859 } |
926 } |
860 PROFILE_FLUSH(); |
|
861 err = iFile.Flush(); |
927 err = iFile.Flush(); |
928 PROFILE_FLUSH(err); |
|
862 if(err != KErrNone) |
929 if(err != KErrNone) |
863 { |
930 { |
864 DoDiscard(); |
931 DoDiscard(); |
865 } |
932 } |
866 iLength = 0; |
933 iLength = 0; |
887 if(iLength == 0) |
954 if(iLength == 0) |
888 { |
955 { |
889 __FILEBUF64_INVARIANT(); |
956 __FILEBUF64_INVARIANT(); |
890 return KErrNone; |
957 return KErrNone; |
891 } |
958 } |
892 PROFILE_WRITE(iFilePos, iLength); |
|
893 TPtrC8 data(iBase, iLength); |
959 TPtrC8 data(iBase, iLength); |
894 TInt err = iFile.Write(iFilePos, data); |
960 TInt err = iFile.Write(iFilePos, data); |
961 PROFILE_WRITE(iFilePos, iLength, err); |
|
895 if(err == KErrNone) |
962 if(err == KErrNone) |
896 { |
963 { |
897 iFileSize = Max(iFileSize, (iFilePos + iLength)); |
964 iFileSize = Max(iFileSize, (iFilePos + iLength)); |
898 } |
965 } |
899 else |
966 else |
1020 iNextReadFilePosHits = 0; |
1087 iNextReadFilePosHits = 0; |
1021 } |
1088 } |
1022 __FILEBUF64_INVARIANT(); |
1089 __FILEBUF64_INVARIANT(); |
1023 } |
1090 } |
1024 |
1091 |
1092 /** |
|
1093 Sets the most appropriate buffer capacity based on the database page size. |
|
1094 The function does a lazy evaluation. The first time the function is called and |
|
1095 aRwDataLength parameter is recognized to be a database or journal page size, the new (optimal) |
|
1096 buffer capacity is calculated and set. All next DoSetCapacity() calls will detect that the new |
|
1097 capacity is already set and will return KErrNone. |
|
1098 |
|
1099 @param aRwDataLength The length of the data being read or written. |
|
1100 @return KErrNone The new capacity was set successfully, |
|
1101 KErrNoMemory Out of memory. |
|
1102 */ |
|
1103 TInt RFileBuf64::DoSetCapacity(TInt aRwDataLength) |
|
1104 { |
|
1105 const TInt KMinPageCount = 4;//the buffer capacity should be at least (KMinPageCount * page size) |
|
1106 //but not less than the original capacity. |
|
1107 const TInt KDefaultPageSize = 1024;//The journal header size is equal to 512 bytes, so it is not easy |
|
1108 //to detect the 512 bytes page size. |
|
1109 |
|
1110 __FBUF64_ASSERT(aRwDataLength > 0, EFBufPanicRwDataLength); |
|
1111 __FILEBUF64_INVARIANT(); |
|
1112 if(iOptimized) |
|
1113 { |
|
1114 __FILEBUF64_INVARIANT(); |
|
1115 return KErrNone; |
|
1116 } |
|
1117 if((aRwDataLength & (aRwDataLength - 1)) != 0 || aRwDataLength < KDefaultPageSize) |
|
1118 { |
|
1119 __FILEBUF64_INVARIANT(); |
|
1120 return KErrNone; |
|
1121 } |
|
1122 //Here: aRwDataLength is power of 2 and is bigger than the default db page size. |
|
1123 //aRwDataLength is the size of the db page. |
|
1124 const TInt pageSize = aRwDataLength; |
|
1125 TInt cnt = iCapacity / pageSize;//how many pages can fit in the buffer now |
|
1126 TInt pageCount = Max(cnt, KMinPageCount);//the number of pages that should fit in the new buffer |
|
1127 TInt newBufCapacity = pageCount * pageSize; |
|
1128 if(newBufCapacity != iCapacity) |
|
1129 { |
|
1130 TUint8* newBase = static_cast <TUint8*> (User::ReAlloc(iBase, newBufCapacity)); |
|
1131 if(!newBase) |
|
1132 { |
|
1133 __FILEBUF64_INVARIANT(); |
|
1134 return KErrNoMemory; |
|
1135 } |
|
1136 iBase = newBase; |
|
1137 iCapacity = newBufCapacity; |
|
1138 //Adjust the initial read-ahead size to be multiple of the page size. |
|
1139 if((iReadAheadSize % pageSize) != 0) |
|
1140 { |
|
1141 TInt q = iReadAheadSize / pageSize; |
|
1142 iReadAheadSize = q != 0 ? pageSize * q : pageSize; |
|
1143 } |
|
1144 } |
|
1145 iOptimized = ETrue; |
|
1146 __FILEBUF64_INVARIANT(); |
|
1147 return KErrNone; |
|
1148 } |
|
1149 |
|
1025 #ifdef _DEBUG |
1150 #ifdef _DEBUG |
1026 |
1151 |
1027 /** |
1152 /** |
1028 RFileBuf64 invariant. Called in _DEBUG mode at the beginning and before the end of every RFileBuf64 method |
1153 RFileBuf64 invariant. Called in _DEBUG mode at the beginning and before the end of every RFileBuf64 method |
1029 (except the init/destroy methods). |
1154 (except the init/destroy methods). |
1035 @panic FBuf64 4 In _DEBUG mode - negative iFilePos value. |
1160 @panic FBuf64 4 In _DEBUG mode - negative iFilePos value. |
1036 @panic FBuf64 5 In _DEBUG mode - set but negative iFileSize value. |
1161 @panic FBuf64 5 In _DEBUG mode - set but negative iFileSize value. |
1037 @panic FBuf64 6 In _DEBUG mode - null file handle (the RFile64 object is not created or already destroyed). |
1162 @panic FBuf64 6 In _DEBUG mode - null file handle (the RFile64 object is not created or already destroyed). |
1038 @panic FBuf64 13 In _DEBUG mode - set but negative iNextReadFilePos value. |
1163 @panic FBuf64 13 In _DEBUG mode - set but negative iNextReadFilePos value. |
1039 @panic FBuf64 14 In _DEBUG mode - negative iNextReadFilePosHits value. |
1164 @panic FBuf64 14 In _DEBUG mode - negative iNextReadFilePosHits value. |
1040 @panic FBuf64 15 In _DEBUG mode - iReadAheadSize is negative or is not power of two. |
1165 @panic FBuf64 15 In _DEBUG mode - iReadAheadSize is negative or is bigger than iCapacity. |
1041 */ |
1166 */ |
1042 void RFileBuf64::Invariant() const |
1167 void RFileBuf64::Invariant() const |
1043 { |
1168 { |
1044 __FBUF64_ASSERT(this != 0, EFBufPanicNullThis); |
1169 __FBUF64_ASSERT(this != 0, EFBufPanicNullThis); |
1045 __FBUF64_ASSERT(iCapacity > 0, EFBufPanicCapacity); |
1170 __FBUF64_ASSERT(iCapacity > 0, EFBufPanicCapacity); |
1048 __FBUF64_ASSERT(iFilePos >= 0, EFBufPanicFilePos); |
1173 __FBUF64_ASSERT(iFilePos >= 0, EFBufPanicFilePos); |
1049 __FBUF64_ASSERT(iFileSize == KFileSizeNotSet || iFileSize >= 0, EFBufPanicFileSize); |
1174 __FBUF64_ASSERT(iFileSize == KFileSizeNotSet || iFileSize >= 0, EFBufPanicFileSize); |
1050 __FBUF64_ASSERT(iFile.SubSessionHandle() != 0, EFBufPanicFileHandle); |
1175 __FBUF64_ASSERT(iFile.SubSessionHandle() != 0, EFBufPanicFileHandle); |
1051 __FBUF64_ASSERT(iNextReadFilePos == KNextReadFilePosNotSet || iNextReadFilePos >= 0, EFBufPanicNextReadFilePos); |
1176 __FBUF64_ASSERT(iNextReadFilePos == KNextReadFilePosNotSet || iNextReadFilePos >= 0, EFBufPanicNextReadFilePos); |
1052 __FBUF64_ASSERT(iNextReadFilePosHits >= 0, EFBufPanicNextReadFilePosHits); |
1177 __FBUF64_ASSERT(iNextReadFilePosHits >= 0, EFBufPanicNextReadFilePosHits); |
1053 __FBUF64_ASSERT(iReadAheadSize > 0 && (iReadAheadSize & (iReadAheadSize - 1)) == 0, EFBufPanicFileBlockSize); |
1178 __FBUF64_ASSERT(iReadAheadSize > 0, EFBufPanicFileBlockSize); |
1054 } |
1179 } |
1055 |
1180 |
1056 #endif |
1181 #endif |