File: blob_entry.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (183 lines) | stat: -rw-r--r-- 6,545 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef STORAGE_BROWSER_BLOB_BLOB_ENTRY_H_
#define STORAGE_BROWSER_BLOB_BLOB_ENTRY_H_

#include <stddef.h>

#include <memory>
#include <string>
#include <vector>

#include "base/component_export.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "storage/browser/blob/blob_memory_controller.h"

namespace storage {
class BlobDataHandle;
class ShareableBlobDataItem;

// Represents a blob in BlobStorageRegistry. Exported only for unit tests.
class COMPONENT_EXPORT(STORAGE_BROWSER) BlobEntry {
 public:
  using TransportAllowedCallback = base::OnceCallback<
      void(BlobStatus, std::vector<BlobMemoryController::FileCreationInfo>)>;
  using BuildAbortedCallback = base::OnceClosure;

  // Records a copy from a referenced blob. Copies happen after referenced blobs
  // are complete & quota for the copies is granted.
  struct COMPONENT_EXPORT(STORAGE_BROWSER) ItemCopyEntry {
    ItemCopyEntry(scoped_refptr<ShareableBlobDataItem> source_item,
                  size_t source_item_offset,
                  scoped_refptr<ShareableBlobDataItem> dest_item);

    ItemCopyEntry(const ItemCopyEntry&) = delete;
    ItemCopyEntry& operator=(const ItemCopyEntry&) = delete;

    ~ItemCopyEntry();
    ItemCopyEntry(ItemCopyEntry&& other);
    BlobEntry::ItemCopyEntry& operator=(BlobEntry::ItemCopyEntry&& rhs);

    scoped_refptr<ShareableBlobDataItem> source_item;
    size_t source_item_offset = 0;
    scoped_refptr<ShareableBlobDataItem> dest_item;
  };

  // Building state for pending blobs. State can include:
  // 1. Waiting for quota to be granted for transport data (PENDING_QUOTA)
  // 2. Waiting for user population of data after quota (PENDING_TRANSPORT)
  // 3. Waiting for blobs we reference to complete & quota granted for possible
  //    copies. (PENDING_REFERENCED_BLOBS)
  struct COMPONENT_EXPORT(STORAGE_BROWSER) BuildingState {
    // |transport_allowed_callback| is not null when data needs population. See
    // BlobStorageContext::BuildBlob for when the callback is called.
    BuildingState(bool transport_items_present,
                  TransportAllowedCallback transport_allowed_callback,
                  size_t num_building_dependent_blobs);

    BuildingState(const BuildingState&) = delete;
    BuildingState& operator=(const BuildingState&) = delete;

    ~BuildingState();

    // Cancels pending memory or file requests, and calls aborted callback if it
    // is set.
    void CancelRequestsAndAbort();

    const bool transport_items_present;
    // We can have trasnport data that's either populated or unpopulated. If we
    // need population, this is populated.
    TransportAllowedCallback transport_allowed_callback;
    std::vector<raw_ptr<ShareableBlobDataItem, VectorExperimental>>
        transport_items;

    BuildAbortedCallback build_aborted_callback;

    // Stores all blobs that we're depending on for building. This keeps the
    // blobs alive while we build our blob.
    std::vector<std::unique_ptr<BlobDataHandle>> dependent_blobs;
    size_t num_building_dependent_blobs;

    base::WeakPtr<BlobMemoryController::QuotaAllocationTask>
        transport_quota_request;

    // Copy quota is always memory.
    base::WeakPtr<BlobMemoryController::QuotaAllocationTask> copy_quota_request;

    // These are copies from a referenced blob item to our blob items. Some of
    // these entries may have changed from bytes to files if they were paged.
    std::vector<ItemCopyEntry> copies;

    // When our blob finishes building these callbacks are called.
    std::vector<BlobStatusCallback> build_completion_callbacks;

    // When our blob is no longer in PENDING_CONSTRUCTION state these callbacks
    // are called.
    std::vector<BlobStatusCallback> build_started_callbacks;
  };

  BlobEntry(const std::string& content_type,
            const std::string& content_disposition);

  BlobEntry(const BlobEntry&) = delete;
  BlobEntry& operator=(const BlobEntry&) = delete;

  ~BlobEntry();

  // Appends the given shared blob data item to this object.
  void AppendSharedBlobItem(scoped_refptr<ShareableBlobDataItem> item);
  void SetSharedBlobItems(
      std::vector<scoped_refptr<ShareableBlobDataItem>> items);

  // Returns if we're a pending blob that can finish building.
  bool CanFinishBuilding() const {
    // PENDING_REFERENCED_BLOBS means transport is finished.
    return status_ == BlobStatus::PENDING_REFERENCED_BLOBS && building_state_ &&
           !building_state_->copy_quota_request &&
           building_state_->num_building_dependent_blobs == 0;
  }

  BlobStatus status() const { return status_; }

  size_t refcount() const { return refcount_; }

  const std::string& content_type() const { return content_type_; }

  const std::string& content_disposition() const {
    return content_disposition_;
  }

  // Total size of this blob in bytes.
  uint64_t total_size() const { return size_; }

  // We record the cumulative offsets of each blob item (except for the first,
  // which would always be 0) to enable binary searching for an item at a
  // specific byte offset.
  const std::vector<uint64_t>& offsets() const { return offsets_; }

  const std::vector<scoped_refptr<ShareableBlobDataItem>>& items() const;

 protected:
  friend class BlobStorageContext;

  void IncrementRefCount() { ++refcount_; }
  void DecrementRefCount() { --refcount_; }

  void set_status(BlobStatus status) { status_ = status; }
  void set_size(uint64_t size) { size_ = size; }

  void ClearItems();
  void ClearOffsets();

  void set_building_state(std::unique_ptr<BuildingState> building_state) {
    building_state_ = std::move(building_state);
  }

 private:
  BlobStatus status_ = BlobStatus::PENDING_QUOTA;
  size_t refcount_ = 0;

  // Metadata.
  std::string content_type_;
  std::string content_disposition_;

  std::vector<scoped_refptr<ShareableBlobDataItem>> items_;

  // Size in bytes. IFF we're a single file then this can be uint64_max.
  uint64_t size_ = 0;

  // Only populated if len(items_) > 1.  Used for binary search.
  // Since the offset of the first item is always 0, we exclude this.
  std::vector<uint64_t> offsets_;

  // Only populated if our status is PENDING_*.
  std::unique_ptr<BuildingState> building_state_;
};

}  // namespace storage
#endif  // STORAGE_BROWSER_BLOB_BLOB_ENTRY_H_