Esempio n. 1
0
void
DOMStorageDBThread::PendingOperations::Add(DOMStorageDBThread::DBOperation* aOperation)
{
  // Optimize: when a key to remove has never been written to disk
  // just bypass this operation.  A kew is new when an operation scheduled
  // to write it to the database is of type opAddItem.
  if (CheckForCoalesceOpportunity(aOperation, DBOperation::opAddItem, DBOperation::opRemoveItem)) {
    mUpdates.Remove(aOperation->Target());
    delete aOperation;
    return;
  }

  // Optimize: when changing a key that is new and has never been
  // written to disk, keep type of the operation to store it at opAddItem.
  // This allows optimization to just forget adding a new key when
  // it is removed from the storage before flush.
  if (CheckForCoalesceOpportunity(aOperation, DBOperation::opAddItem, DBOperation::opUpdateItem)) {
    aOperation->mType = DBOperation::opAddItem;
  }

  // Optimize: to prevent lose of remove operation on a key when doing
  // remove/set/remove on a previously existing key we have to change
  // opAddItem to opUpdateItem on the new operation when there is opRemoveItem
  // pending for the key.
  if (CheckForCoalesceOpportunity(aOperation, DBOperation::opRemoveItem, DBOperation::opAddItem)) {
    aOperation->mType = DBOperation::opUpdateItem;
  }

  switch (aOperation->Type())
  {
  // Operations on single keys

  case DBOperation::opAddItem:
  case DBOperation::opUpdateItem:
  case DBOperation::opRemoveItem:
    // Override any existing operation for the target (=scope+key).
    mUpdates.Put(aOperation->Target(), aOperation);
    break;

  // Clear operations

  case DBOperation::opClear:
  case DBOperation::opClearMatchingScope:
    // Drop all update (insert/remove) operations for equivavelent or matching scope.
    // We do this as an optimization as well as a must based on the logic,
    // if we would not delete the update tasks, changes would have been stored
    // to the database after clear operations have been executed.
    mUpdates.Enumerate(ForgetUpdatesForScope, aOperation);
    mClears.Put(aOperation->Target(), aOperation);
    break;

  case DBOperation::opClearAll:
    // Drop simply everything, this is a super-operation.
    mUpdates.Clear();
    mClears.Clear();
    mClears.Put(aOperation->Target(), aOperation);
    break;

  default:
    MOZ_ASSERT(false);
    break;
  }
}
Esempio n. 2
0
void
StorageDBThread::PendingOperations::Add(StorageDBThread::DBOperation* aOperation)
{
  // Optimize: when a key to remove has never been written to disk
  // just bypass this operation.  A key is new when an operation scheduled
  // to write it to the database is of type opAddItem.
  if (CheckForCoalesceOpportunity(aOperation, DBOperation::opAddItem,
                                  DBOperation::opRemoveItem)) {
    mUpdates.Remove(aOperation->Target());
    delete aOperation;
    return;
  }

  // Optimize: when changing a key that is new and has never been
  // written to disk, keep type of the operation to store it at opAddItem.
  // This allows optimization to just forget adding a new key when
  // it is removed from the storage before flush.
  if (CheckForCoalesceOpportunity(aOperation, DBOperation::opAddItem,
                                  DBOperation::opUpdateItem)) {
    aOperation->mType = DBOperation::opAddItem;
  }

  // Optimize: to prevent lose of remove operation on a key when doing
  // remove/set/remove on a previously existing key we have to change
  // opAddItem to opUpdateItem on the new operation when there is opRemoveItem
  // pending for the key.
  if (CheckForCoalesceOpportunity(aOperation, DBOperation::opRemoveItem,
                                  DBOperation::opAddItem)) {
    aOperation->mType = DBOperation::opUpdateItem;
  }

  switch (aOperation->Type())
  {
  // Operations on single keys

  case DBOperation::opAddItem:
  case DBOperation::opUpdateItem:
  case DBOperation::opRemoveItem:
    // Override any existing operation for the target (=scope+key).
    mUpdates.Put(aOperation->Target(), aOperation);
    break;

  // Clear operations

  case DBOperation::opClear:
  case DBOperation::opClearMatchingOrigin:
  case DBOperation::opClearMatchingOriginAttributes:
    // Drop all update (insert/remove) operations for equivavelent or matching
    // scope.  We do this as an optimization as well as a must based on the
    // logic, if we would not delete the update tasks, changes would have been
    // stored to the database after clear operations have been executed.
    for (auto iter = mUpdates.Iter(); !iter.Done(); iter.Next()) {
      nsAutoPtr<DBOperation>& pendingTask = iter.Data();

      if (aOperation->Type() == DBOperation::opClear &&
          (pendingTask->OriginNoSuffix() != aOperation->OriginNoSuffix() ||
           pendingTask->OriginSuffix() != aOperation->OriginSuffix())) {
        continue;
      }

      if (aOperation->Type() == DBOperation::opClearMatchingOrigin &&
          !StringBeginsWith(pendingTask->OriginNoSuffix(), aOperation->Origin())) {
        continue;
      }

      if (aOperation->Type() == DBOperation::opClearMatchingOriginAttributes &&
          !OriginPatternMatches(pendingTask->OriginSuffix(), aOperation->OriginPattern())) {
        continue;
      }

      iter.Remove();
    }

    mClears.Put(aOperation->Target(), aOperation);
    break;

  case DBOperation::opClearAll:
    // Drop simply everything, this is a super-operation.
    mUpdates.Clear();
    mClears.Clear();
    mClears.Put(aOperation->Target(), aOperation);
    break;

  default:
    MOZ_ASSERT(false);
    break;
  }
}