/*
* Copyright 2014 WANdisco
*
* WANdisco licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/**
* The c5db.log package contains services that provide logging for c5db.replication.
* <p>
* C5 replication is an implementation of the Raft consensus protocol, with some
* modifications. It works by bringing multiple nodes into perfect agreement on a
* sequence of entries, each of which can represent e.g. edits to a database,
* or some other state machine transition. That sequence of entries is called the
* nodes' log.
* <p>
* There are two main entry points for external agents to interface with the log.
* One is {@link c5db.interfaces.LogModule}, which describes a service for starting
* and stopping the log, connecting it up, and accessing its data. The second is
* {@link c5db.interfaces.replication.ReplicatorLog} which is the interface to
* the log that an individual Replicator sees and uses; in other words, ReplicatorLog
* describes the logging capabilities needed by the Raft algorithm.
* <p>
* At present, the c5db.log package provides one implementation of the Raft log,
* accessed through interface {@link c5db.log.OLog}; external agents essentially
* interact with OLog through adapters. The provided implementation is
* {@link c5db.log.QuorumDelegatingLog}.
* <p>
* An important concept is that of "quorums." A quorum is essentially what the Raft
* algorithm describes as a "cluster." It is the set of independent entities (what
* C5 represents by {@link c5db.interfaces.replication.Replicator}) that coordinate
* to replicate entries. A quorum is identified by a string unique to it called its
* quorum ID. A single log may provide services for Replicators representing more
* than one quorum; indeed, LogModule, and OLog behind it, are designed to handle
* all the quorums on a given server. There's nothing preventing more than one instance
* of OLog and/or LogModule from running on a given server; it just isn't necessary.
* <p>
* In addition, there's nothing preventing more than one JVM instance from hosting
* OLog instances on a given machine; in fact, all cooperating replicators for a
* single quorum may all be in one server, one JVM instance, and/or one machine,
* although from the standpoint of hardware fault tolerance there is no reason to do
* so. For more information about how quorums are used, see LogModule and
* {@link c5db.interfaces.ReplicationModule}.
* <p>
* OLog's entries are {@link c5db.log.OLogEntry}. These are for the most part
* agnostic about their payload, which could represent any sort of instructions or
* objects the user wants to replicate. However, OLogEntry also can represent
* information needed by Raft itself; for instance, quorum configuration changes
* are handled by replicating special instances of OLogEntry.
* <p>
* QuorumDelegatingLog makes use of {@link c5db.log.LogPersistenceService} to abstract
* away all the information about the medium to which the log is persisted. At
* present, c5db.log provides one implementation, {@link c5db.log.LogFileService},
* which writes the log(s) to local file system files. QuorumDelegatingLog is
* so named because it gives each quorum its own local log file, and distributes
* log actions (appends, truncations, rolls) to each as necessary. This simplifies
* the implementation at the cost of locality of writes. A different implementation
* of OLog and of LogPersistenceService could choose to put different quorums'
* entries in the same physical file.
* <p>
* The file-like abstraction used internally is
* {@link c5db.log.LogPersistenceService.BytePersistence}. Operations with the
* LogPersistenceService are expressed by manipulating BytePersistence instances.
* As mentioned, LogFileService implements BytePersistence with IO to a file system
* file.
* <p>
* Although "logically" in the Raft algorithm each quorum has a single log continuity,
* the implementation may distribute that log across several BytePersistence objects.
* (e.g. in our case, files). That keeps the log file from growing without bound; at
* some point, the file can be closed and a new file started. This operation is
* called "rolling". The old file may be stored for some time in case it is needed
* by either the Raft algorithm or for failure recovery; and eventually when it is
* no longer needed it can be deleted.
* <p>
* {@link c5db.log.EncodedSequentialLog} is the class that handles operations within
* a single BytePersistence, and therefore also within a single quorum. It can
* provide iterators over the entries stored within one persistence. These iterators
* are used by the clients of the replication system in case they need to replay
* earlier logged data (for instance, for recovery).
*/
package c5db.log;