示例#1
0
void
CacheFileChunk::UpdateDataSize(uint32_t aOffset, uint32_t aLen, bool aEOF)
{
  mFile->AssertOwnsLock();

  MOZ_ASSERT(!aEOF, "Implement me! What to do with opened streams?");
  MOZ_ASSERT(aOffset <= mDataSize);
  MOZ_ASSERT(aLen != 0);

  // UpdateDataSize() is called only when we've written some data to the chunk
  // and we never write data anymore once some error occurs.
  MOZ_ASSERT(NS_SUCCEEDED(mStatus));

  LOG(("CacheFileChunk::UpdateDataSize() [this=%p, offset=%d, len=%d, EOF=%d]",
       this, aOffset, aLen, aEOF));

  mIsDirty = true;

  int64_t fileSize = kChunkSize * mIndex + aOffset + aLen;
  bool notify = false;

  if (fileSize > mFile->mDataSize)
    mFile->mDataSize = fileSize;

  if (aOffset + aLen > mDataSize) {
    mDataSize = aOffset + aLen;
    notify = true;
  }

  if (mState == READY || mState == WRITING) {
    MOZ_ASSERT(mValidityMap.Length() == 0);

    if (notify) {
      NotifyUpdateListeners();
    }

    return;
  }

  // We're still waiting for data from the disk. This chunk cannot be used by
  // input stream, so there must be no update listener. We also need to keep
  // track of where the data is written so that we can correctly merge the new
  // data with the old one.

  MOZ_ASSERT(mUpdateListeners.Length() == 0);
  MOZ_ASSERT(mState == READING);

  mValidityMap.AddPair(aOffset, aLen);
  mValidityMap.Log();
}
示例#2
0
void
CacheFileChunk::UpdateDataSize(uint32_t aOffset, uint32_t aLen, bool aEOF)
{
  mFile->AssertOwnsLock();

  MOZ_ASSERT(!aEOF, "Implement me! What to do with opened streams?");
  MOZ_ASSERT(aOffset <= mDataSize);

  LOG(("CacheFileChunk::UpdateDataSize() [this=%p, offset=%d, len=%d, EOF=%d]",
       this, aOffset, aLen, aEOF));

  mIsDirty = true;

  int64_t fileSize = kChunkSize * mIndex + aOffset + aLen;
  bool notify = false;

  if (fileSize > mFile->mDataSize)
    mFile->mDataSize = fileSize;

  if (aOffset + aLen > mDataSize) {
    mDataSize = aOffset + aLen;
    notify = true;
  }

  if (mState == READY || mState == WRITING) {
    MOZ_ASSERT(mValidityMap.Length() == 0);

    if (notify)
      NotifyUpdateListeners();

    return;
  }

  // We're still waiting for data from the disk. This chunk cannot be used by
  // input stream, so there must be no update listener. We also need to keep
  // track of where the data is written so that we can correctly merge the new
  // data with the old one.

  MOZ_ASSERT(mUpdateListeners.Length() == 0);
  MOZ_ASSERT(mState == READING);

  ValidityPair pair(aOffset, aLen);

  if (mValidityMap.Length() == 0) {
    mValidityMap.AppendElement(pair);
    return;
  }


  // Find out where to place this pair into the map, it can overlap with
  // one preceding pair and all subsequent pairs.
  uint32_t pos = 0;
  for (pos = mValidityMap.Length() ; pos > 0 ; pos--) {
    if (mValidityMap[pos-1].LessThan(pair)) {
      if (mValidityMap[pos-1].Overlaps(pair)) {
        // Merge with the preceding pair
        mValidityMap[pos-1].Merge(pair);
        pos--; // Point to the updated pair
      }
      else {
        if (pos == mValidityMap.Length())
          mValidityMap.AppendElement(pair);
        else
          mValidityMap.InsertElementAt(pos, pair);
      }

      break;
    }
  }

  if (!pos)
    mValidityMap.InsertElementAt(0, pair);

  // Now pos points to merged or inserted pair, check whether it overlaps with
  // subsequent pairs.
  while (pos + 1 < mValidityMap.Length()) {
    if (mValidityMap[pos].Overlaps(mValidityMap[pos + 1])) {
      mValidityMap[pos].Merge(mValidityMap[pos + 1]);
      mValidityMap.RemoveElementAt(pos + 1);
    }
    else {
      break;
    }
  }
}