| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef NET_DISK_CACHE_FLASH_SEGMENT_H_ | |
| 6 #define NET_DISK_CACHE_FLASH_SEGMENT_H_ | |
| 7 | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/gtest_prod_util.h" | |
| 12 #include "net/base/net_export.h" | |
| 13 | |
| 14 namespace disk_cache { | |
| 15 | |
| 16 class Storage; | |
| 17 | |
| 18 // The underlying storage represented by Storage class, is divided into fixed | |
| 19 // size logical segments, represented by this class. Since segment size is | |
| 20 // fixed, the storage size should be a multiple of segment size. The picture | |
| 21 // below describes the relation between storage and segments: | |
| 22 // | |
| 23 // |-----------+-----------+-----+-------------+-----------| | |
| 24 // | segment 0 | segment 1 | ... | segment n-1 | segment n | | |
| 25 // |-----------+-----------+-----+-------------+-----------| | |
| 26 // | |
| 27 // |-------------------------------------------------------| | |
| 28 // | storage | | |
| 29 // |-------------------------------------------------------| | |
| 30 // | |
| 31 // A segment is constructed by taking its index within the storage, a flag | |
| 32 // indicating whether it is a read-only segment and a pointer to the storage on | |
| 33 // which it resides. It provides an API for reading/writing entries residing on | |
| 34 // it. Init() function must be called right after the construction of a segment | |
| 35 // and one should proceed to calling other functions only if Init() has | |
| 36 // succeeded. After a successful initialization, one may proceed to call | |
| 37 // non-mutating functions; mutating functions can be called if the segment is | |
| 38 // not read-only. Finally, Close() function must be called right before the | |
| 39 // destruction. Calling Close() makes the segment immutable, which means | |
| 40 // mutating functions cannot be called on the object after that. | |
| 41 // | |
| 42 // Segment can only be used as a log, i.e. all writes are laid out sequentially | |
| 43 // on a segment. As a result, WriteData() function does not take an offset. | |
| 44 // Current write offset can be learned by calling write_offset(). | |
| 45 // | |
| 46 // Once the entries are written to the Segment and Close() called on it and the | |
| 47 // object destroyed, we should later be able to instantiate a read-only Segment | |
| 48 // object and recreate all the entries that were previously written to it. To | |
| 49 // achieve this, a tiny region of Segment is used for its metadata and Segment | |
| 50 // provides two calls for interacting with metadata: StoreOffset() and | |
| 51 // GetOffsets(). The former can be used to store an offset that was returned by | |
| 52 // write_offset() and the latter can be used to retrieve all the offsets that | |
| 53 // were stored in the Segment. Before attempting to write an entry, the client | |
| 54 // should call CanHold() to make sure that there is enough space in the segment. | |
| 55 // | |
| 56 // ReadData can be called over the range that was previously written with | |
| 57 // WriteData. Reading from area that was not written will fail. | |
| 58 | |
| 59 class NET_EXPORT_PRIVATE Segment { | |
| 60 public: | |
| 61 // |index| is the index of this segment on |storage|. If the storage size is | |
| 62 // X and the segment size is Y, where X >> Y and X % Y == 0, then the valid | |
| 63 // values for the index are integers within the range [0, X/Y). Thus, if | |
| 64 // |index| is given value Z, then it covers bytes on storage starting at the | |
| 65 // offset Z*Y and ending at the offset Z*Y+Y-1. | |
| 66 Segment(int32 index, bool read_only, Storage* storage); | |
| 67 ~Segment(); | |
| 68 | |
| 69 int32 index() const { return index_; } | |
| 70 int32 write_offset() const { return write_offset_; } | |
| 71 | |
| 72 bool HaveOffset(int32 offset) const; | |
| 73 std::vector<int32> GetOffsets() const { return offsets_; } | |
| 74 | |
| 75 // Manage the number of users of this segment. | |
| 76 void AddUser(); | |
| 77 void ReleaseUser(); | |
| 78 bool HasNoUsers() const; | |
| 79 | |
| 80 // Performs segment initialization. Must be the first function called on the | |
| 81 // segment and further calls should be made only if it is successful. | |
| 82 bool Init(); | |
| 83 | |
| 84 // Writes |size| bytes of data from |buffer| to segment, returns false if | |
| 85 // fails and true if succeeds. Can block for a long time. | |
| 86 bool WriteData(const void* buffer, int32 size); | |
| 87 | |
| 88 // Reads |size| bytes of data living at |offset| into |buffer| returns true on | |
| 89 // success and false on failure. | |
| 90 bool ReadData(void* buffer, int32 size, int32 offset) const; | |
| 91 | |
| 92 // Stores the offset in the metadata. | |
| 93 void StoreOffset(int32 offset); | |
| 94 | |
| 95 // Closes the segment, returns true on success and false on failure. Closing | |
| 96 // a segment makes it immutable. | |
| 97 bool Close(); | |
| 98 | |
| 99 // Returns true if segment can accommodate an entry of |size| bytes. | |
| 100 bool CanHold(int32 size) const; | |
| 101 | |
| 102 private: | |
| 103 int32 index_; | |
| 104 int32 num_users_; | |
| 105 bool read_only_; // Indicates whether the segment can be written to. | |
| 106 bool init_; // Indicates whether segment was initialized. | |
| 107 Storage* storage_; // Storage on which the segment resides. | |
| 108 const int32 offset_; // Offset of the segment on |storage_|. | |
| 109 const int32 summary_offset_; // Offset of the segment summary. | |
| 110 int32 write_offset_; // Current write offset. | |
| 111 std::vector<int32> offsets_; | |
| 112 | |
| 113 DISALLOW_COPY_AND_ASSIGN(Segment); | |
| 114 }; | |
| 115 | |
| 116 } // namespace disk_cache | |
| 117 | |
| 118 #endif // NET_DISK_CACHE_FLASH_SEGMENT_H_ | |
| OLD | NEW |