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/// `LogStore` serves as a Write-Ahead-Log for storage engine.
34#[async_trait::async_trait]
35pub trait LogStore: Send + Sync + 'static + std::fmt::Debug {
36    type Error: ErrorExt + Send + Sync + 'static;
37
38    /// Stops components of the logstore.
39    async fn stop(&self) -> Result<(), Self::Error>;
40
41    /// Appends a batch of entries and returns a response containing a map where the key is a region id
42    /// while the value is the id of the last successfully written entry of the region.
43    async fn append_batch(&self, entries: Vec<Entry>) -> Result<AppendBatchResponse, Self::Error>;
44
45    /// Creates a new `EntryStream` to asynchronously generates `Entry` with ids
46    /// starting from `id`.
47    async fn read(
48        &self,
49        provider: &Provider,
50        id: EntryId,
51    ) -> Result<SendableEntryStream<'static, Entry, Self::Error>, Self::Error>;
52
53    /// Creates a new `Namespace` from the given ref.
54    async fn create_namespace(&self, ns: &Provider) -> Result<(), Self::Error>;
55
56    /// Deletes an existing `Namespace` specified by the given ref.
57    async fn delete_namespace(&self, ns: &Provider) -> Result<(), Self::Error>;
58
59    /// Lists all existing namespaces.
60    async fn list_namespaces(&self) -> Result<Vec<Provider>, Self::Error>;
61
62    /// Marks all entries with ids `<=entry_id` of the given `namespace` as obsolete,
63    /// so that the log store can safely delete those entries. This method does not guarantee
64    /// that the obsolete entries are deleted immediately.
65    async fn obsolete(
66        &self,
67        provider: &Provider,
68        region_id: RegionId,
69        entry_id: EntryId,
70    ) -> Result<(), Self::Error>;
71
72    /// Marks all entries of a region as obsolete and removes its dedicated namespace when
73    /// supported by the backend.
74    async fn obsolete_all(
75        &self,
76        provider: &Provider,
77        region_id: RegionId,
78    ) -> Result<(), Self::Error>;
79
80    /// Makes an entry instance of the associated Entry type
81    fn entry(
82        &self,
83        data: Vec<u8>,
84        entry_id: EntryId,
85        region_id: RegionId,
86        provider: &Provider,
87    ) -> Result<Entry, Self::Error>;
88
89    /// Returns the latest entry id in the log store.
90    fn latest_entry_id(&self, provider: &Provider) -> Result<EntryId, Self::Error>;
91
92    /// Waits until every entry of the provider's region with an id at or below
93    /// `entry_id` has the persistence this log store guarantees for an
94    /// acknowledged append, so that a caller can persist `entry_id` as a
95    /// replay watermark.
96    ///
97    /// The default returns at once and keeps each log store's own
98    /// acknowledgement guarantee, whatever it is: Raft Engine with
99    /// `sync_write = false`, for example, acknowledges an append before its
100    /// periodic sync. A log store that acknowledges an append before its
101    /// entries have that persistence overrides this method.
102    async fn wait_durable(
103        &self,
104        _provider: &Provider,
105        _entry_id: EntryId,
106    ) -> Result<(), Self::Error> {
107        Ok(())
108    }
109
110    /// Releases every entry of a region the caller dropped, after `obsolete`
111    /// marked them obsolete, so that the log store keeps none of them even
112    /// across a restart, which never opens the region again to mark its
113    /// entries obsolete.
114    ///
115    /// The default does nothing and keeps each log store's existing handling
116    /// of a dropped region. A log store that keeps obsolete marks only in
117    /// memory overrides this method and returns once the release is durable.
118    async fn release_region(
119        &self,
120        _provider: &Provider,
121        _region_id: RegionId,
122    ) -> Result<(), Self::Error> {
123        Ok(())
124    }
125}
126
127/// The response of an `append` operation.
128#[derive(Debug, Default)]
129pub struct AppendResponse {
130    /// The id of the entry appended to the log store.
131    pub last_entry_id: EntryId,
132}
133
134/// The response of an `append_batch` operation.
135#[derive(Debug, Default)]
136pub struct AppendBatchResponse {
137    /// Key: region id (as u64). Value: the id of the last successfully written entry of the region.
138    pub last_entry_ids: HashMap<RegionId, EntryId>,
139}