blob: 7dc57aa0790bce2e0e4de2632c3fbf85d36458cc [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_DISK_CACHE_FLASH_LOG_STORE_H_
#define NET_DISK_CACHE_FLASH_LOG_STORE_H_
#include <set>
#include <vector>
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "net/base/net_export.h"
namespace disk_cache {
class Segment;
class Storage;
// This class implements a general purpose store for storing and retrieving
// entries consisting of arbitrary binary data. The store has log semantics,
// i.e. it's not possible to overwrite data in place. In order to update an
// entry, a new version must be written. Only one entry can be written to at
// any given time, while concurrent reading of multiple entries is supported.
class NET_EXPORT_PRIVATE LogStore {
public:
explicit LogStore(Storage* storage);
~LogStore();
// Performs initialization. Must be the first function called and further
// calls should be made only if it is successful.
bool Init();
// Closes the store. Should be the last function called before destruction.
bool Close();
// Creates an entry of |size| bytes. The id of the created entry is stored in
// |entry_id|.
bool CreateEntry(int32 size, int32* entry_id);
// TODO(agayev): Add DeleteEntry.
// Appends data to the end of the last created entry.
bool WriteData(const void* buffer, int32 size);
// Opens an entry with id |entry_id|.
bool OpenEntry(int32 entry_id);
// Reads |size| bytes starting from |offset| into |buffer|, where |offset| is
// relative to the entry's content, from an entry identified by |entry_id|.
bool ReadData(int32 entry_id, void* buffer, int32 size, int32 offset) const;
// Closes an entry that was either opened with OpenEntry or created with
// CreateEntry.
void CloseEntry(int32 id);
private:
FRIEND_TEST_ALL_PREFIXES(FlashCacheTest,
LogStoreReadFromClosedSegment);
FRIEND_TEST_ALL_PREFIXES(FlashCacheTest,
LogStoreSegmentSelectionIsFifo);
FRIEND_TEST_ALL_PREFIXES(FlashCacheTest,
LogStoreInUseSegmentIsSkipped);
FRIEND_TEST_ALL_PREFIXES(FlashCacheTest,
LogStoreReadFromCurrentAfterClose);
int32 GetNextSegmentIndex();
bool InUse(int32 segment_index) const;
Storage* storage_;
int32 num_segments_;
// Currently open segments, either for reading or writing. There can only be
// one segment open for writing, and multiple open for reading.
std::vector<Segment*> open_segments_;
// The index of the segment currently being written to. It's an index to
// |open_segments_| vector.
int32 write_index_;
// Ids of entries currently open, either CreatEntry'ed or OpenEntry'ed.
std::set<int32> open_entries_;
// Id of the entry that is currently being written to, -1 if there is no entry
// currently being written to.
int32 current_entry_id_;
// Number of bytes left to be written to the entry identified by
// |current_entry_id_|. Its value makes sense iff |current_entry_id_| is not
// -1.
int32 current_entry_num_bytes_left_to_write_;
bool init_; // Init was called.
bool closed_; // Close was called.
DISALLOW_COPY_AND_ASSIGN(LogStore);
};
} // namespace disk_cache
#endif // NET_DISK_CACHE_FLASH_LOG_STORE_H_