15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_DISK_CACHE_FLASH_SEGMENT_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_DISK_CACHE_FLASH_SEGMENT_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace disk_cache { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Storage; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The underlying storage represented by Storage class, is divided into fixed 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// size logical segments, represented by this class. Since segment size is 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fixed, the storage size should be a multiple of segment size. The picture 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// below describes the relation between storage and segments: 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |-----------+-----------+-----+-------------+-----------| 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// | segment 0 | segment 1 | ... | segment n-1 | segment n | 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |-----------+-----------+-----+-------------+-----------| 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |-------------------------------------------------------| 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// | storage | 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |-------------------------------------------------------| 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A segment is constructed by taking its index within the storage, a flag 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// indicating whether it is a read-only segment and a pointer to the storage on 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which it resides. It provides an API for reading/writing entries residing on 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it. Init() function must be called right after the construction of a segment 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and one should proceed to calling other functions only if Init() has 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// succeeded. After a successful initialization, one may proceed to call 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-mutating functions; mutating functions can be called if the segment is 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not read-only. Finally, Close() function must be called right before the 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destruction. Calling Close() makes the segment immutable, which means 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mutating functions cannot be called on the object after that. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Segment can only be used as a log, i.e. all writes are laid out sequentially 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// on a segment. As a result, WriteData() function does not take an offset. 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Current write offset can be learned by calling write_offset(). 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Once the entries are written to the Segment and Close() called on it and the 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object destroyed, we should later be able to instantiate a read-only Segment 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object and recreate all the entries that were previously written to it. To 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// achieve this, a tiny region of Segment is used for its metadata and Segment 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provides two calls for interacting with metadata: StoreOffset() and 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetOffsets(). The former can be used to store an offset that was returned by 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// write_offset() and the latter can be used to retrieve all the offsets that 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// were stored in the Segment. Before attempting to write an entry, the client 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should call CanHold() to make sure that there is enough space in the segment. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReadData can be called over the range that was previously written with 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WriteData. Reading from area that was not written will fail. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NET_EXPORT_PRIVATE Segment { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |index| is the index of this segment on |storage|. If the storage size is 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // X and the segment size is Y, where X >> Y and X % Y == 0, then the valid 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // values for the index are integers within the range [0, X/Y). Thus, if 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |index| is given value Z, then it covers bytes on storage starting at the 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // offset Z*Y and ending at the offset Z*Y+Y-1. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Segment(int32 index, bool read_only, Storage* storage); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~Segment(); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 index() const { return index_; } 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 write_offset() const { return write_offset_; } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool HaveOffset(int32 offset) const; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int32> GetOffsets() const { return offsets_; } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Manage the number of users of this segment. 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddUser(); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReleaseUser(); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool HasNoUsers() const; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs segment initialization. Must be the first function called on the 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // segment and further calls should be made only if it is successful. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Init(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Writes |size| bytes of data from |buffer| to segment, returns false if 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // fails and true if succeeds. Can block for a long time. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool WriteData(const void* buffer, int32 size); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reads |size| bytes of data living at |offset| into |buffer| returns true on 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // success and false on failure. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadData(void* buffer, int32 size, int32 offset) const; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stores the offset in the metadata. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StoreOffset(int32 offset); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Closes the segment, returns true on success and false on failure. Closing 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a segment makes it immutable. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Close(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if segment can accommodate an entry of |size| bytes. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CanHold(int32 size) const; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 index_; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 num_users_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool read_only_; // Indicates whether the segment can be written to. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool init_; // Indicates whether segment was initialized. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Storage* storage_; // Storage on which the segment resides. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int32 offset_; // Offset of the segment on |storage_|. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int32 summary_offset_; // Offset of the segment summary. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 write_offset_; // Current write offset. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int32> offsets_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Segment); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace disk_cache 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_DISK_CACHE_FLASH_SEGMENT_H_ 119