Skip to main content

store_api/
logstore.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! LogStore APIs.
16
17pub mod entry;
18pub mod provider;
19
20use std::collections::HashMap;
21use std::pin::Pin;
22
23use common_error::ext::ErrorExt;
24use entry::Entry;
25use futures::Stream;
26
27pub type SendableEntryStream<'a, I, E> = Pin<Box<dyn Stream<Item = Result<Vec<I>, E>> + Send + 'a>>;
28
29pub use crate::logstore::entry::Id as EntryId;
30use crate::logstore::provider::Provider;
31use crate::storage::RegionId;
32
33// The information used to locate WAL index for the specified region.
34#[derive(Debug, Clone, Copy)]
35pub struct WalIndex {
36    pub region_id: RegionId,
37    pub location_id: u64,
38}
39
40impl WalIndex {
41    pub fn new(region_id: RegionId, location_id: u64) -> Self {
42        Self {
43            region_id,
44            location_id,
45        }
46    }
47}
48
49/// `LogStore` serves as a Write-Ahead-Log for storage engine.
50#[async_trait::async_trait]
51pub trait LogStore: Send + Sync + 'static + std::fmt::Debug {
52    type Error: ErrorExt + Send + Sync + 'static;
53
54    /// Stops components of the logstore.
55    async fn stop(&self) -> Result<(), Self::Error>;
56
57    /// Appends a batch of entries and returns a response containing a map where the key is a region id
58    /// while the value is the id of the last successfully written entry of the region.
59    async fn append_batch(&self, entries: Vec<Entry>) -> Result<AppendBatchResponse, Self::Error>;
60
61    /// Creates a new `EntryStream` to asynchronously generates `Entry` with ids
62    /// starting from `id`.
63    async fn read(
64        &self,
65        provider: &Provider,
66        id: EntryId,
67        index: Option<WalIndex>,
68    ) -> Result<SendableEntryStream<'static, Entry, Self::Error>, Self::Error>;
69
70    /// Creates a new `Namespace` from the given ref.
71    async fn create_namespace(&self, ns: &Provider) -> Result<(), Self::Error>;
72
73    /// Deletes an existing `Namespace` specified by the given ref.
74    async fn delete_namespace(&self, ns: &Provider) -> Result<(), Self::Error>;
75
76    /// Lists all existing namespaces.
77    async fn list_namespaces(&self) -> Result<Vec<Provider>, Self::Error>;
78
79    /// Marks all entries with ids `<=entry_id` of the given `namespace` as obsolete,
80    /// so that the log store can safely delete those entries. This method does not guarantee
81    /// that the obsolete entries are deleted immediately.
82    async fn obsolete(
83        &self,
84        provider: &Provider,
85        region_id: RegionId,
86        entry_id: EntryId,
87    ) -> Result<(), Self::Error>;
88
89    /// Marks all entries of a region as obsolete and removes its dedicated namespace when
90    /// supported by the backend.
91    async fn obsolete_all(
92        &self,
93        provider: &Provider,
94        region_id: RegionId,
95    ) -> Result<(), Self::Error>;
96
97    /// Makes an entry instance of the associated Entry type
98    fn entry(
99        &self,
100        data: Vec<u8>,
101        entry_id: EntryId,
102        region_id: RegionId,
103        provider: &Provider,
104    ) -> Result<Entry, Self::Error>;
105
106    /// Returns the latest entry id in the log store.
107    fn latest_entry_id(&self, provider: &Provider) -> Result<EntryId, Self::Error>;
108
109    /// Waits until every entry of the provider's region with an id at or below
110    /// `entry_id` has the persistence this log store guarantees for an
111    /// acknowledged append, so that a caller can persist `entry_id` as a
112    /// replay watermark.
113    ///
114    /// The default returns at once and keeps each log store's own
115    /// acknowledgement guarantee, whatever it is: Raft Engine with
116    /// `sync_write = false`, for example, acknowledges an append before its
117    /// periodic sync. A log store that acknowledges an append before its
118    /// entries have that persistence overrides this method.
119    async fn wait_durable(
120        &self,
121        _provider: &Provider,
122        _entry_id: EntryId,
123    ) -> Result<(), Self::Error> {
124        Ok(())
125    }
126}
127
128/// The response of an `append` operation.
129#[derive(Debug, Default)]
130pub struct AppendResponse {
131    /// The id of the entry appended to the log store.
132    pub last_entry_id: EntryId,
133}
134
135/// The response of an `append_batch` operation.
136#[derive(Debug, Default)]
137pub struct AppendBatchResponse {
138    /// Key: region id (as u64). Value: the id of the last successfully written entry of the region.
139    pub last_entry_ids: HashMap<RegionId, EntryId>,
140}