blob: 1013afd0d09686462525d510bbb749a6071d0883 [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_DB_H_
#define PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_DB_H_
#include <functional>
#include <memory>
#include <lib/callback/operation_serializer.h>
#include <lib/timekeeper/clock.h>
#include "lib/fxl/strings/concatenate.h"
#include "peridot/bin/ledger/app/page_utils.h"
#include "peridot/bin/ledger/app/types.h"
#include "peridot/bin/ledger/coroutine/coroutine.h"
#include "peridot/bin/ledger/storage/impl/leveldb.h"
#include "peridot/bin/ledger/storage/public/db.h"
#include "peridot/bin/ledger/storage/public/iterator.h"
#include "peridot/bin/ledger/storage/public/types.h"
namespace ledger {
// |PageUsageDb| persists all information on page usage.
//
// Calls to |MarkPageOpened| and |MarkPageClosed| will update the underlying
// database in the order in which they are called.
//
// Rows in the underlying database are serialized as follows:
// Last usage row:
// - Key: "opened/<ledger_name><page_id>"
// - Value: "<timestamp>" or timestamp 0 for open pages
class PageUsageDb {
public:
PageUsageDb(timekeeper::Clock* clock, std::unique_ptr<storage::Db> db);
~PageUsageDb();
// Marks the page with the given id as opened. |INTERNAL_ERROR| is returned if
// the operation is interrupted.
Status MarkPageOpened(coroutine::CoroutineHandler* handler,
fxl::StringView ledger_name,
storage::PageIdView page_id);
// Marks the page with the given id as closed. |INTERNAL_ERROR| is returned if
// the operation is interrupted.
Status MarkPageClosed(coroutine::CoroutineHandler* handler,
fxl::StringView ledger_name,
storage::PageIdView page_id);
// Marks the page with the given id as evicted. |INTERNAL_ERROR| is returned
// if the operation is interrupted.
Status MarkPageEvicted(coroutine::CoroutineHandler* handler,
fxl::StringView ledger_name,
storage::PageIdView page_id);
// Marks all open pages as closed. |INTERNAL_ERROR| is returned if the
// operation is interrupted.
Status MarkAllPagesClosed(coroutine::CoroutineHandler* handler);
// Updates |pages| to contain an iterator over all entries of page
// information.
Status GetPages(coroutine::CoroutineHandler* handler,
std::unique_ptr<storage::Iterator<const PageInfo>>* pages);
private:
// Inserts the given |key|-|value| pair in the underlying database.
Status Put(coroutine::CoroutineHandler* handler, fxl::StringView key,
fxl::StringView value);
// Deletes the row with the given |key| in the underlying database.
Status Delete(coroutine::CoroutineHandler* handler, fxl::StringView key);
timekeeper::Clock* clock_;
std::unique_ptr<storage::Db> db_;
// A serializer used for Put and Delete. Both these operations need to be
// serialized to guarantee that consecutive calls to update the contents of a
// single page (e.g. a page is opened and then closed) are written in |db_| in
// the right order, i.e. the order in which they were called.
callback::OperationSerializer serializer_;
FXL_DISALLOW_COPY_AND_ASSIGN(PageUsageDb);
};
} // namespace ledger
#endif // PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_DB_H_