| Index: storage/browser/blob/shareable_blob_data_item.h | 
| diff --git a/storage/browser/blob/shareable_blob_data_item.h b/storage/browser/blob/shareable_blob_data_item.h | 
| index 4c2f9c1833262d18dfa82b622abdfef8585b9541..b356c0c78a13f465456c0ff12d7fcaff7103ff77 100644 | 
| --- a/storage/browser/blob/shareable_blob_data_item.h | 
| +++ b/storage/browser/blob/shareable_blob_data_item.h | 
| @@ -7,44 +7,101 @@ | 
|  | 
| #include <string> | 
|  | 
| +#include "base/callback_helpers.h" | 
| #include "base/containers/hash_tables.h" | 
| #include "base/hash.h" | 
| #include "base/macros.h" | 
| #include "base/memory/ref_counted.h" | 
| +#include "storage/browser/blob/blob_memory_controller.h" | 
| +#include "storage/browser/storage_browser_export.h" | 
| #include "storage/common/data_element.h" | 
|  | 
| namespace storage { | 
| class BlobDataItem; | 
| class InternalBlobData; | 
|  | 
| -// This class allows blob items to be shared between blobs, and is only used by | 
| -// BlobStorageContext. This class contains both the blob data item and the uuids | 
| -// of all the blobs using this item. | 
| +// This class allows blob items to be shared between blobs.  This class contains | 
| +// both the blob data item and the uuids of all the blobs using this item. | 
| // The data in this class (the item) is immutable, but the item itself can be | 
| // swapped out with an item with the same data but a different backing (think | 
| // RAM vs file backed). | 
| -class ShareableBlobDataItem : public base::RefCounted<ShareableBlobDataItem> { | 
| +// We also allow the storage of a deletion closure which is used for memory | 
| +// quota reclamation. | 
| +class STORAGE_EXPORT ShareableBlobDataItem | 
| +    : public base::RefCounted<ShareableBlobDataItem> { | 
| public: | 
| -  ShareableBlobDataItem(const std::string& blob_uuid, | 
| -                        const scoped_refptr<BlobDataItem>& item); | 
| +  enum State { | 
| +    // We're an item that needs quota (either disk or memory). | 
| +    QUOTA_NEEDED, | 
| +    // We have requested quota from the BlobMemoryController. | 
| +    QUOTA_REQUESTED, | 
| +    // Space has been allocated for this item in the BlobMemoryController, but | 
| +    // it may not yet be populated. | 
| +    QUOTA_GRANTED, | 
| +    // We're a populated item that needed quota. | 
| +    POPULATED_WITH_QUOTA, | 
| +    // We're a populated item that didn't need quota. | 
| +    POPULATED_WITHOUT_QUOTA | 
| +  }; | 
|  | 
| -  const scoped_refptr<BlobDataItem>& item(); | 
| +  ShareableBlobDataItem(const std::string& referencing_blob_uuid, | 
| +                        scoped_refptr<BlobDataItem> item, | 
| +                        State state); | 
|  | 
| -  base::hash_set<std::string>& referencing_blobs() { | 
| +  const scoped_refptr<BlobDataItem>& item() const { return item_; } | 
| +  void set_item(scoped_refptr<BlobDataItem> item); | 
| + | 
| +  // This is a unique auto-incrementing id assigned to this item on | 
| +  // construction. It is used to keep track of this item in an LRU data | 
| +  // structure for eviction to disk. | 
| +  uint64_t item_id() const { return item_id_; } | 
| + | 
| +  const base::hash_set<std::string>& referencing_blobs() const { | 
| return referencing_blobs_; | 
| } | 
| +  base::hash_set<std::string>* referencing_blobs_mutable() { | 
| +    return &referencing_blobs_; | 
| +  } | 
| + | 
| +  State state() const { return state_; } | 
| +  void set_state(State state) { state_ = state; } | 
| + | 
| +  bool IsPopulated() const { | 
| +    return state_ == POPULATED_WITH_QUOTA || state_ == POPULATED_WITHOUT_QUOTA; | 
| +  } | 
| + | 
| +  bool HasGrantedQuota() const { | 
| +    return state_ == POPULATED_WITH_QUOTA || state_ == QUOTA_GRANTED; | 
| +  } | 
|  | 
| private: | 
| +  friend class BlobMemoryController; | 
| +  friend class BlobMemoryControllerTest; | 
| friend class base::RefCounted<ShareableBlobDataItem>; | 
| -  friend class InternalBlobData; | 
| +  friend STORAGE_EXPORT void PrintTo(const ShareableBlobDataItem& x, | 
| +                                     ::std::ostream* os); | 
| + | 
| ~ShareableBlobDataItem(); | 
|  | 
| -  scoped_refptr<BlobDataItem> item_; | 
| +  void set_memory_allocation( | 
| +      std::unique_ptr<BlobMemoryController::MemoryAllocation> allocation) { | 
| +    memory_allocation_ = std::move(allocation); | 
| +  } | 
|  | 
| +  // This is a unique identifier for this ShareableBlobDataItem. | 
| +  const uint64_t item_id_; | 
| +  State state_; | 
| +  scoped_refptr<BlobDataItem> item_; | 
| base::hash_set<std::string> referencing_blobs_; | 
| +  std::unique_ptr<BlobMemoryController::MemoryAllocation> memory_allocation_; | 
|  | 
| DISALLOW_COPY_AND_ASSIGN(ShareableBlobDataItem); | 
| }; | 
|  | 
| +STORAGE_EXPORT bool operator==(const ShareableBlobDataItem& a, | 
| +                               const ShareableBlobDataItem& b); | 
| +STORAGE_EXPORT bool operator!=(const ShareableBlobDataItem& a, | 
| +                               const ShareableBlobDataItem& b); | 
| + | 
| }  // namespace storage | 
| #endif  // STORAGE_BROWSER_BLOB_SHAREABLE_BLOB_DATA_ITEM_H_ | 
|  |