summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/disk_cache/flash/segment.cc21
-rw-r--r--net/disk_cache/flash/segment.h41
-rw-r--r--net/disk_cache/flash/segment_unittest.cc38
3 files changed, 34 insertions, 66 deletions
diff --git a/net/disk_cache/flash/segment.cc b/net/disk_cache/flash/segment.cc
index b00b38a..191ccd7 100644
--- a/net/disk_cache/flash/segment.cc
+++ b/net/disk_cache/flash/segment.cc
@@ -44,7 +44,7 @@ bool Segment::Init() {
DCHECK_LE(entry_count, kFlashMaxEntryCount);
std::vector<int32> tmp(summary + 1, summary + 1 + entry_count);
- header_offsets_.swap(tmp);
+ offsets_.swap(tmp);
init_ = true;
return true;
}
@@ -61,14 +61,9 @@ bool Segment::WriteData(const void* buffer, int32 size, int32* offset) {
return true;
}
-bool Segment::WriteHeader(const void* header, int32 size, int32* offset) {
- int32 my_offset;
- if (!WriteData(header, size, &my_offset))
- return false;
- if (offset)
- *offset = my_offset;
- header_offsets_.push_back(my_offset);
- return true;
+void Segment::StoreOffset(int32 offset) {
+ DCHECK(offsets_.size() < kFlashMaxEntryCount);
+ offsets_.push_back(offset);
}
bool Segment::ReadData(void* buffer, int32 size, int32 offset) const {
@@ -81,12 +76,12 @@ bool Segment::Close() {
if (read_only_)
return true;
- DCHECK(header_offsets_.size() <= kFlashMaxEntryCount);
+ DCHECK(offsets_.size() <= kFlashMaxEntryCount);
int32 summary[kFlashMaxEntryCount + 1];
memset(summary, 0, kFlashSummarySize);
- summary[0] = header_offsets_.size();
- std::copy(header_offsets_.begin(), header_offsets_.end(), summary + 1);
+ summary[0] = offsets_.size();
+ std::copy(offsets_.begin(), offsets_.end(), summary + 1);
if (!storage_->Write(summary, kFlashSummarySize, summary_offset_))
return false;
@@ -95,7 +90,7 @@ bool Segment::Close() {
}
bool Segment::CanHold(int32 size) const {
- return header_offsets_.size() < kFlashMaxEntryCount &&
+ return offsets_.size() < kFlashMaxEntryCount &&
write_offset_ + size <= summary_offset_;
}
diff --git a/net/disk_cache/flash/segment.h b/net/disk_cache/flash/segment.h
index 4a10c65..3c1fa67 100644
--- a/net/disk_cache/flash/segment.h
+++ b/net/disk_cache/flash/segment.h
@@ -40,22 +40,21 @@ class Storage;
// mutating functions cannot be called on the object after that.
//
// Segment can only be used as a log, i.e. all writes are laid out sequentially
-// on a segment. As a result, write APIs do not take an offset, but can return
-// an offset of where the write took place. The entries living on a segment are
-// expected to consist of data part and header part where the header holds
-// enough information to identify all the data belonging to it. The difference
-// between WriteData and WriteHeader is that writes issued with the latter have
-// their offsets saved in the metadata, which can later be retrieved. Thus, it
-// is up to the client to specify data layout and associate the header with
-// data. For example the client may issue WriteData calls and save the offsets
-// which then can be written using WriteHeader. Note that it is possible to
-// write entries using just WriteHeader as well, for example if it is an entry
-// of the format where header specifies the length of the following data.
-// Before attempting to write an entry, the client should call CanHold to make
-// sure that there is enough space in the segment.
+// on a segment. As a result, WriteData() function does not take an offset, but
+// can return an offset of where the write took place.
+//
+// Once the entries are written to the Segment and Close() called on it and the
+// object destroyed, we should later be able to instantiate a read-only Segment
+// object and recreate all the entries that were previously written to it. To
+// achieve this, a tiny region of Segment is used for its metadata and Segment
+// provides two calls for interacting with metadata: StoreOffset() and
+// GetOffsets(). The former can be used to store an offset that was returned by
+// WriteData() and the latter can be used to retrieve all the offsets that were
+// stored in the Segment. Before attempting to write an entry, the client
+// should call CanHold() to make sure that there is enough space in the segment.
//
// ReadData can be called over the range that was previously written with
-// WriteData/WriteHeader. Reading from area that was not written will fail.
+// WriteData. Reading from area that was not written will fail.
class NET_EXPORT_PRIVATE Segment {
public:
@@ -67,7 +66,7 @@ class NET_EXPORT_PRIVATE Segment {
Segment(int32 index, bool read_only, Storage* storage);
~Segment();
- const std::vector<int32>& header_offsets() const { return header_offsets_; }
+ std::vector<int32> GetOffsets() const { return offsets_; }
// Performs segment initialization. Must be the first function called on the
// segment and further calls should be made only if it is successful.
@@ -78,17 +77,13 @@ class NET_EXPORT_PRIVATE Segment {
// block for a long time.
bool WriteData(const void* buffer, int32 size, int32* offset);
- // Writes |header| of |size| bytes, returns false if fails and true if
- // succeeds and sets the |offset|, if it is not NULL. Can block for a long
- // time. The difference between this function and WriteData is that the
- // offset of this write operation is saved in the segment metadata and can
- // later be retrieved via |header_offsets|.
- bool WriteHeader(const void* header, int32 size, int32* offset);
-
// Reads |size| bytes of data living at |offset| into |buffer|, returns true
// on success and false on failure.
bool ReadData(void* buffer, int32 size, int32 offset) const;
+ // Stores the offset in the metadata.
+ void StoreOffset(int32 offset);
+
// Closes the segment, returns true on success and false on failure. Closing
// a segment makes it immutable.
bool Close();
@@ -103,7 +98,7 @@ class NET_EXPORT_PRIVATE Segment {
const int32 offset_; // Offset of the segment on |storage_|.
const int32 summary_offset_; // Offset of the segment summary.
int32 write_offset_; // Current write offset.
- std::vector<int32> header_offsets_;
+ std::vector<int32> offsets_;
DISALLOW_COPY_AND_ASSIGN(Segment);
};
diff --git a/net/disk_cache/flash/segment_unittest.cc b/net/disk_cache/flash/segment_unittest.cc
index bbbcc80..fb9fb33 100644
--- a/net/disk_cache/flash/segment_unittest.cc
+++ b/net/disk_cache/flash/segment_unittest.cc
@@ -77,30 +77,6 @@ TEST_F(FlashCacheTest, WriteDataReadData) {
EXPECT_TRUE(segment->Close());
}
-TEST_F(FlashCacheTest, WriteHeaderReadData) {
- int32 index = rand() % num_segments_in_storage_;
- scoped_ptr<disk_cache::Segment> segment(
- new disk_cache::Segment(index, false, storage_.get()));
-
- EXPECT_TRUE(segment->Init());
- SmallEntry entry1;
- EXPECT_TRUE(segment->CanHold(entry1.size));
- int32 offset;
- EXPECT_TRUE(segment->WriteHeader(entry1.data, entry1.size, &offset));
- EXPECT_EQ(1u, segment->header_offsets().size());
- EXPECT_EQ(offset, segment->header_offsets().front());
- EXPECT_TRUE(segment->Close());
-
- segment.reset(new disk_cache::Segment(index, true, storage_.get()));
- EXPECT_TRUE(segment->Init());
- SmallEntry entry2;
- EXPECT_EQ(1u, segment->header_offsets().size());
- offset = segment->header_offsets().front();
- EXPECT_TRUE(segment->ReadData(entry2.data, entry2.size, offset));
- EXPECT_EQ(entry1, entry2);
- EXPECT_TRUE(segment->Close());
-}
-
TEST_F(FlashCacheTest, FillWithSmallEntries) {
int32 index = rand() % num_segments_in_storage_;
scoped_ptr<disk_cache::Segment> segment(
@@ -109,14 +85,15 @@ TEST_F(FlashCacheTest, FillWithSmallEntries) {
EXPECT_TRUE(segment->Init());
SmallEntry entry;
int32 num_bytes_written = 0;
+ int32 offset;
while (segment->CanHold(entry.size)) {
- EXPECT_TRUE(segment->WriteHeader(entry.data, entry.size, NULL));
+ EXPECT_TRUE(segment->WriteData(entry.data, entry.size, &offset));
+ segment->StoreOffset(offset);
num_bytes_written += entry.size;
}
int32 space_left = kSegmentFreeSpace - num_bytes_written;
EXPECT_GE(space_left, entry.size);
- EXPECT_EQ(segment->header_offsets().size(),
- disk_cache::kFlashMaxEntryCount);
+ EXPECT_EQ(segment->GetOffsets().size(), disk_cache::kFlashMaxEntryCount);
EXPECT_TRUE(segment->Close());
}
@@ -128,13 +105,14 @@ TEST_F(FlashCacheTest, FillWithLargeEntries) {
EXPECT_TRUE(segment->Init());
scoped_ptr<LargeEntry> entry(new LargeEntry);
int32 num_bytes_written = 0;
+ int32 offset;
while (segment->CanHold(entry->size)) {
- EXPECT_TRUE(segment->WriteHeader(entry->data, entry->size, NULL));
+ EXPECT_TRUE(segment->WriteData(entry->data, entry->size, &offset));
+ segment->StoreOffset(offset);
num_bytes_written += entry->size;
}
int32 space_left = kSegmentFreeSpace - num_bytes_written;
EXPECT_LT(space_left, entry->size);
- EXPECT_LT(segment->header_offsets().size(),
- disk_cache::kFlashMaxEntryCount);
+ EXPECT_LT(segment->GetOffsets().size(), disk_cache::kFlashMaxEntryCount);
EXPECT_TRUE(segment->Close());
}