webengine/osswebengine/cache/src/HttpCachePostponeWriteUtilities.cpp
changeset 11 c8a366e56285
parent 10 a359256acfc6
child 25 0ed94ceaa377
equal deleted inserted replaced
10:a359256acfc6 11:c8a366e56285
   192 // -----------------------------------------------------------------------------
   192 // -----------------------------------------------------------------------------
   193 //
   193 //
   194 void CSegmentedHeapBuffer::AppendL(TInt& aRemainder, const TDesC8& aDes)
   194 void CSegmentedHeapBuffer::AppendL(TInt& aRemainder, const TDesC8& aDes)
   195     {
   195     {
   196     aRemainder = aDes.Length(); // consumed nothing yet.
   196     aRemainder = aDes.Length(); // consumed nothing yet.
   197     TInt workingLen;
       
   198     TInt workingOffset=0;   // read position in source descriptor
       
   199     HBufC8* currentBuffer;
   197     HBufC8* currentBuffer;
   200 
   198 
       
   199     // 90% of cached objects are less than 4KB.
       
   200     // Lots of them also come in two parts from the http stack.
       
   201 #define HTTPSEGMENTEDBUFFER_OPTION_INCREMENT_GRADUALLY
       
   202 #ifndef HTTPSEGMENTEDBUFFER_OPTION_INCREMENT_GRADUALLY
   201     TInt lastBuffer = iBufferList.Count()-1;
   203     TInt lastBuffer = iBufferList.Count()-1;
   202     if ( lastBuffer < 0 )
   204     if ( lastBuffer < 0 )
   203         {
   205         {
   204         // TODO: Make the first block only equal to the size of data we need?
   206         // TODO: Make the first block only equal to the size of data we need?
   205         // Take some traces to see what happens.
   207         // Take some traces to see what happens.
   206 
       
   207         // no blocks allocated.  May leave here if we can't get space.
   208         // no blocks allocated.  May leave here if we can't get space.
   208         currentBuffer = HBufC8::NewLC(iBufferSize);
   209         currentBuffer = HBufC8::NewLC(iBufferSize);
   209         iBufferList.AppendL(currentBuffer);
   210         iBufferList.AppendL(currentBuffer);
   210         CleanupStack::Pop(currentBuffer);
   211         CleanupStack::Pop(currentBuffer);
   211         lastBuffer = 0;
   212         lastBuffer = 0;
   213     else
   214     else
   214         {
   215         {
   215         currentBuffer = iBufferList[lastBuffer];
   216         currentBuffer = iBufferList[lastBuffer];
   216         }
   217         }
   217 
   218 
       
   219     TInt workingLen;
       
   220     TInt workingOffset=0;   // read position in source descriptor
   218     // here, currentBuffer always points to a buffer we can use.
   221     // here, currentBuffer always points to a buffer we can use.
   219     while ( aRemainder )
   222     while ( aRemainder )
   220         {
   223         {
   221         workingLen = iBufferSize - currentBuffer->Length(); // workingLen = amount of space left in this segment
   224         workingLen = iBufferSize - currentBuffer->Length(); // workingLen = amount of space left in this segment
   222         workingLen = (aRemainder > workingLen) ? workingLen : aRemainder;   // workingLen = smaller of (amount of data left in source) or (amount of space left in current segment)
   225         workingLen = (aRemainder > workingLen) ? workingLen : aRemainder;   // workingLen = smaller of (amount of data left in source) or (amount of space left in current segment)
   234             currentBuffer = HBufC8::NewLC(iBufferSize);
   237             currentBuffer = HBufC8::NewLC(iBufferSize);
   235             iBufferList.AppendL(currentBuffer);
   238             iBufferList.AppendL(currentBuffer);
   236             CleanupStack::Pop(currentBuffer);
   239             CleanupStack::Pop(currentBuffer);
   237             }
   240             }
   238         }
   241         }
       
   242 #else
       
   243 #ifdef __CACHELOG__
       
   244     HttpCacheUtil::WriteFormatLog(0, _L("CHttpCacheSegmentedBuffer::AppendL %08x adding %d bytes to %d"), this, aRemainder, this->Length());
       
   245 #endif
       
   246     // because most items are small, increment buffers up to the configured segment size as data is added...
       
   247     TInt workingOffset = 0;
       
   248     TInt lastBuffer = iBufferList.Count()-1;
       
   249     if ( lastBuffer < 0 )
       
   250         {
       
   251         // special case for first allocation.
       
   252         // no blocks allocated.  May leave here if we can't get space.
       
   253         if( aRemainder <= iBufferSize)  // we can fit the first block into a single segment
       
   254             {
       
   255 #ifdef __CACHELOG__
       
   256             HttpCacheUtil::WriteFormatLog(0, _L(" First alloc %d into buffer fits inside %d"), aRemainder, iBufferSize );
       
   257 #endif
       
   258             // fast path optimisation for first alloc into an empty segmented buffer.
       
   259             currentBuffer = aDes.AllocLC();
       
   260             iBufferList.AppendL( currentBuffer );
       
   261             CleanupStack::Pop( currentBuffer );
       
   262             aRemainder = 0;
       
   263             }
       
   264         else
       
   265             {
       
   266             // the segmented buffer is empty and the first block to add is bigger than the configured block size
       
   267             // fill the first segment and leave the rest for the loop
       
   268 #ifdef __CACHELOG__
       
   269             HttpCacheUtil::WriteFormatLog(0, _L(" First alloc %d is bigger than %d"), aRemainder, iBufferSize );
       
   270 #endif
       
   271             currentBuffer = HBufC8::NewLC( iBufferSize );
       
   272             iBufferList.AppendL( currentBuffer );
       
   273             CleanupStack::Pop( currentBuffer );
       
   274             currentBuffer->Des().Copy( aDes.Ptr(), iBufferSize );
       
   275             workingOffset = iBufferSize;    // when we add the remaining data, we start from here.
       
   276             aRemainder -= iBufferSize;
       
   277             }
       
   278         }
       
   279     else
       
   280         {
       
   281 #ifdef __CACHELOG__
       
   282         HttpCacheUtil::WriteFormatLog(0, _L(" Buffer already contains data"));
       
   283 #endif
       
   284         currentBuffer = iBufferList[lastBuffer];
       
   285         }
       
   286     
       
   287     // When we get to here the following state applies.
       
   288     // currentBuffer points to an allocated and filled HBufC8
       
   289     // workingOffset tells us how far into the supplied descriptor the data we want is
       
   290     // aRemainder tells us how much data is left to copy.
       
   291     while( aRemainder )
       
   292         {
       
   293 #ifdef __CACHELOG__
       
   294         HttpCacheUtil::WriteFormatLog(0, _L(" %d bytes left to add to buffer"), aRemainder);
       
   295 #endif
       
   296         TInt possibleConsumptionInThisBlock = iBufferSize - currentBuffer->Length();
       
   297         if( possibleConsumptionInThisBlock == 0 )
       
   298             {
       
   299 #ifdef __CACHELOG__
       
   300             HttpCacheUtil::WriteFormatLog(0, _L(" Buffer cannot be extended."));
       
   301 #endif
       
   302             // block cannot extend, alloc a new one
       
   303             // the new one is either the correct length, or iBufferSize if aRemainder is too big.
       
   304             TInt spaceToAlloc = aRemainder < iBufferSize ? aRemainder : iBufferSize;
       
   305             currentBuffer = HBufC8::NewLC( spaceToAlloc );
       
   306             iBufferList.AppendL( currentBuffer );
       
   307             CleanupStack::Pop( currentBuffer );
       
   308             possibleConsumptionInThisBlock = spaceToAlloc;            
       
   309 #ifdef __CACHELOG__
       
   310             HttpCacheUtil::WriteFormatLog(0, _L(" New buffer of %d bytes allocated"), spaceToAlloc);
       
   311 #endif
       
   312             // fill the block as far as possible
       
   313             currentBuffer->Des().Append( aDes.Mid( workingOffset, possibleConsumptionInThisBlock ));
       
   314             workingOffset += possibleConsumptionInThisBlock;
       
   315             aRemainder -= possibleConsumptionInThisBlock;
       
   316             }
       
   317         else
       
   318             {
       
   319             // block can extend
       
   320             if( possibleConsumptionInThisBlock >= aRemainder )
       
   321                 {
       
   322 #ifdef __CACHELOG__
       
   323                 HttpCacheUtil::WriteFormatLog(0, _L(" Current buffer can be extended to hold all data."));
       
   324 #endif
       
   325                 // we can realloc this buffer big enough to hold all the remaining data.
       
   326                 currentBuffer = currentBuffer->ReAllocL( currentBuffer->Length() + aRemainder );
       
   327                 CleanupStack::PushL( currentBuffer );
       
   328                 iBufferList.Remove(iBufferList.Count()-1);
       
   329                 iBufferList.AppendL( currentBuffer );
       
   330                 CleanupStack::Pop( currentBuffer );
       
   331                 // copy the data
       
   332                 currentBuffer->Des().Append( aDes.Mid( workingOffset, aRemainder ));
       
   333                 aRemainder = 0;
       
   334                 }
       
   335             else
       
   336                 {
       
   337 #ifdef __CACHELOG__
       
   338                 HttpCacheUtil::WriteFormatLog(0, _L(" Buffer cannot be extended to hold all data, consuming %d bytes."), possibleConsumptionInThisBlock);
       
   339 #endif
       
   340                 // this buffer cannot extend to hold all the data.
       
   341                 // take as much as we can - we will allocate a new buffer next time around.
       
   342                 currentBuffer = currentBuffer->ReAllocL( currentBuffer->Length() + possibleConsumptionInThisBlock );
       
   343                 CleanupStack::PushL( currentBuffer );
       
   344                 iBufferList.Remove(iBufferList.Count()-1);
       
   345                 iBufferList.AppendL( currentBuffer );
       
   346                 CleanupStack::Pop( currentBuffer );
       
   347                 // copy the data
       
   348                 currentBuffer->Des().Append( aDes.Mid( workingOffset, possibleConsumptionInThisBlock ));
       
   349                 // set up variables for next time around
       
   350                 workingOffset += possibleConsumptionInThisBlock;
       
   351                 aRemainder -= possibleConsumptionInThisBlock;
       
   352                 }
       
   353             }
       
   354         }
       
   355 #endif
       
   356 #ifdef __CACHELOG__
       
   357     HttpCacheUtil::WriteFormatLog(0, _L(" exiting AppendL. Segmented buffer now contains %d bytes"), this->Length());
       
   358 #endif
   239     // will only exit here if we consumed all data
   359     // will only exit here if we consumed all data
   240     }
   360     }
   241 
   361 
   242 // -----------------------------------------------------------------------------
   362 // -----------------------------------------------------------------------------
   243 // CSegmentedHeapBuffer::Length
   363 // CSegmentedHeapBuffer::Length
   348 // -----------------------------------------------------------------------------
   468 // -----------------------------------------------------------------------------
   349 // CHttpCacheWriteTimeout::CHttpCacheWriteTimeout
   469 // CHttpCacheWriteTimeout::CHttpCacheWriteTimeout
   350 // -----------------------------------------------------------------------------
   470 // -----------------------------------------------------------------------------
   351 //
   471 //
   352 CHttpCacheWriteTimeout::CHttpCacheWriteTimeout( const TInt aTimeout )
   472 CHttpCacheWriteTimeout::CHttpCacheWriteTimeout( const TInt aTimeout )
   353     : CActive(EPriorityStandard),
   473     : CActive(EPriorityIdle),
   354       iTimeout(aTimeout) // Standard priority
   474       iTimeout(aTimeout) // Standard priority
   355     {
   475     {
   356     }
   476     }
   357 
   477 
   358 // -----------------------------------------------------------------------------
   478 // -----------------------------------------------------------------------------