// ----------------------------------------------------------------------
// File: ShardDirectory.hh
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* quarkdb - a redis-like highly available key-value store *
* Copyright (C) 2016 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#ifndef __QUARKDB_SHARD_DIRECTORY_H__
#define __QUARKDB_SHARD_DIRECTORY_H__
#include
#include "Common.hh"
#include "Configuration.hh"
#include "Status.hh"
#include "utils/Resilvering.hh"
namespace quarkdb {
class StateMachine; class RaftJournal; class Configuration;
// Snapshot of a shard. The underlying snapshot directory is deleted upon object's
// deletion, it is thus not suitable for long-lived backups.
class ShardSnapshot {
public:
ShardSnapshot(const std::string &path);
~ShardSnapshot();
std::string getPath();
private:
const std::string path;
};
using ShardID = std::string;
using ResilveringEventID = std::string;
using SnapshotID = std::string;
// Manages a shard directory on the physical file system.
// Keeps ownership of StateMachine and RaftJournal - initialized lazily.
class ShardDirectory {
public:
ShardDirectory(const std::string &path, Configuration config = {});
~ShardDirectory();
StateMachine *getStateMachineForBulkload();
StateMachine *getStateMachine();
RaftJournal *getRaftJournal();
bool hasRaftJournal(std::string &err) const;
// Reset the contents of both the state machine and the raft journal.
// Physical paths remain the same.
void obliterate(RaftClusterID clusterID, const std::vector &nodes,
LogIndex startIndex, FsyncPolicy fsyncPolicy, std::unique_ptr existingContents);
// Create a standalone shard.
static ShardDirectory* create(const std::string &path, RaftClusterID clusterID, ShardID shardID, std::unique_ptr sm, Status &st);
// Create a consensus shard.
static ShardDirectory* create(const std::string &path, RaftClusterID clusterID, ShardID shardID, const std::vector &nodes, LogIndex startIndex, FsyncPolicy fsyncPolicy, std::unique_ptr sm, Status &st);
std::unique_ptr takeSnapshot(const SnapshotID &id, std::string &err);
bool resilveringStart(const ResilveringEventID &id, std::string &err);
bool resilveringCopy(const ResilveringEventID &id, std::string_view filename, std::string_view contents, std::string &err);
bool resilveringFinish(const ResilveringEventID &id, std::string &err);
const ResilveringHistory& getResilveringHistory() const;
// empty string in case of success - otherwise contains the error
// TODO: replace with proper status object
std::string checkpoint(std::string_view path);
//----------------------------------------------------------------------------
// Initialize our StateMachine with the given source, if any.
// If no source is given, create a brand new one.
//----------------------------------------------------------------------------
void initializeStateMachine(std::unique_ptr sm, LogIndex initialLastApplied);
//----------------------------------------------------------------------------
// Wipe out StateMachine contents.
//----------------------------------------------------------------------------
void wipeoutStateMachineContents();
private:
void parseResilveringHistory();
void storeResilveringHistory();
void detach();
std::string path;
Configuration configuration;
ShardID shardID;
StateMachine *smptr = nullptr;
RaftJournal *journalptr = nullptr;
ResilveringHistory resilveringHistory;
std::string stateMachinePath() const;
std::string raftJournalPath() const;
std::string currentPath() const;
std::string resilveringHistoryPath();
std::string getSupplanted(const ResilveringEventID &id);
std::string getResilveringArena(const ResilveringEventID &id);
std::string getTempSnapshot(const SnapshotID &id);
static Status initializeDirectory(const std::string &path, RaftClusterID clusterID, ShardID shardID);
};
}
#endif