void
DOMStorageManager::ClearCaches(uint32_t aUnloadFlags,
                               const OriginAttributesPattern& aPattern,
                               const nsACString& aOriginScope)
{
  for (auto iter1 = mCaches.Iter(); !iter1.Done(); iter1.Next()) {
    PrincipalOriginAttributes oa;
    DebugOnly<bool> rv = oa.PopulateFromSuffix(iter1.Key());
    MOZ_ASSERT(rv);
    if (!aPattern.Matches(oa)) {
      // This table doesn't match the given origin attributes pattern
      continue;
    }

    CacheOriginHashtable* table = iter1.Data();

    for (auto iter2 = table->Iter(); !iter2.Done(); iter2.Next()) {
      DOMStorageCache* cache = iter2.Get()->cache();

      if (aOriginScope.IsEmpty() ||
          StringBeginsWith(cache->OriginNoSuffix(), aOriginScope)) {
        cache->UnloadItems(aUnloadFlags);
      }
    }
  }
}
void
SessionStorageManager::ClearStorages(ClearStorageType aType,
                                     const OriginAttributesPattern& aPattern,
                                     const nsACString& aOriginScope)
{
  for (auto iter1 = mOATable.Iter(); !iter1.Done(); iter1.Next()) {
    OriginAttributes oa;
    DebugOnly<bool> ok = oa.PopulateFromSuffix(iter1.Key());
    MOZ_ASSERT(ok);
    if (!aPattern.Matches(oa)) {
      // This table doesn't match the given origin attributes pattern
      continue;
    }

    OriginKeyHashTable* table = iter1.Data();
    for (auto iter2 = table->Iter(); !iter2.Done(); iter2.Next()) {
      if (aOriginScope.IsEmpty() ||
          StringBeginsWith(iter2.Key(), aOriginScope)) {
        if (aType == eAll) {
          iter2.Data()->Clear(SessionStorageCache::eDefaultSetType, false);
          iter2.Data()->Clear(SessionStorageCache::eSessionSetType, false);
        } else {
          MOZ_ASSERT(aType == eSessionOnly);
          iter2.Data()->Clear(SessionStorageCache::eSessionSetType, false);
        }
      }
    }
  }
}