-
Notifications
You must be signed in to change notification settings - Fork 766
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Introduced
MetaSpec
for setting relative expiration (#14041)
This is a compatible change with new feature provided. - This commit introduces a new type, `MetaSpec`, which specifies content of the `KVMeta` to be stored for a key. This new type is particularly utilized in `upsert` requests to enable the setting of relative expiration times. Previously, the `KVMeta` type was used directly for this purpose. However, to avoid impacting existing storage data types, `MetaSpec` has been specifically added for use in `upsert` operations. When applying a raft-log, a `KVMeta` is built from `MetaSpec`. Designed with backward compatibility, `MetaSpec` maintains a serialized format compatible with `KVMeta`, ensuring no disruption to existing functionality. - We introduce two new types `Time` and `Interval` to reprensent serde-able time stamp and time interval. - Tests are added to ensure meta-service works correctly with API with ttl support, but databend-query does not use these API yet.
- v1.2.704-nightly
- v1.2.703-nightly
- v1.2.702-nightly
- v1.2.701-nightly
- v1.2.700-nightly
- v1.2.699-nightly
- v1.2.698-nightly
- v1.2.697
- v1.2.697-nightly
- v1.2.696-nightly
- v1.2.695-nightly
- v1.2.694-nightly
- v1.2.693-nightly
- v1.2.692-nightly
- v1.2.691-nightly
- v1.2.690-nightly
- v1.2.689-nightly
- v1.2.688-nightly
- v1.2.687-nightly
- v1.2.686-nightly
- v1.2.685-nightly
- v1.2.684-nightly
- v1.2.683-nightly
- v1.2.682-nightly
- v1.2.681-nightly
- v1.2.680
- v1.2.680-p3
- v1.2.680-p2
- v1.2.680-p1
- v1.2.680-nightly
- v1.2.679-nightly
- v1.2.678-nightly
- v1.2.677-nightly
- v1.2.676-nightly
- v1.2.675-nightly
- v1.2.674-nightly
- v1.2.673-nightly
- v1.2.672-nightly
- v1.2.671-nightly
- v1.2.670-nightly
- v1.2.669-nightly
- v1.2.668-nightly
- v1.2.667-nightly
- v1.2.666-nightly
- v1.2.665-nightly
- v1.2.664-nightly
- v1.2.663-nightly
- v1.2.662-nightly
- v1.2.661-nightly
- v1.2.660-nightly
- v1.2.659-nightly
- v1.2.658-nightly
- v1.2.657-nightly
- v1.2.656-nightly
- v1.2.655-nightly
- v1.2.654-nightly
- v1.2.653-nightly
- v1.2.652-nightly
- v1.2.651-nightly
- v1.2.650-nightly
- v1.2.649-nightly
- v1.2.648-nightly
- v1.2.647-nightly
- v1.2.646-nightly
- v1.2.645-nightly
- v1.2.644-nightly
- v1.2.643-nightly
- v1.2.642-nightly
- v1.2.641-nightly
- v1.2.640-nightly
- v1.2.639-nightly
- v1.2.638-nightly
- v1.2.637-nightly
- v1.2.636-rc8.2
- v1.2.636-rc8.1
- v1.2.636-nightly
- v1.2.635-nightly
- v1.2.634-nightly
- v1.2.633-nightly
- v1.2.632-nightly
- v1.2.631-nightly
- v1.2.630-nightly
- v1.2.629-nightly
- v1.2.628-nightly
- v1.2.627-nightly
- v1.2.626-nightly
- v1.2.625-nightly
- v1.2.624-nightly
- v1.2.623-nightly
- v1.2.622-nightly
- v1.2.621-nightly
- v1.2.620-nightly
- v1.2.619-nightly
- v1.2.618-nightly
- v1.2.617-nightly
- v1.2.616-nightly
- v1.2.615
- v1.2.615-nightly
- v1.2.614-nightly
- v1.2.613-nightly
- v1.2.612-nightly
- v1.2.611-nightly
- v1.2.610-nightly
- v1.2.609
- v1.2.609-nightly
- v1.2.608-nightly
- v1.2.607-nightly
- v1.2.606-nightly
- v1.2.605-nightly
- v1.2.604-nightly
- v1.2.603-nightly
- v1.2.602-nightly
- v1.2.601-nightly
- v1.2.600-nightly
- v1.2.599-nightly
- v1.2.598-nightly
- v1.2.597-nightly
- v1.2.596-nightly
- v1.2.595-nightly
- v1.2.594-nightly
- v1.2.593-nightly
- v1.2.592-nightly
- v1.2.591-nightly
- v1.2.590-nightly
- v1.2.589-nightly
- v1.2.588-nightly
- v1.2.587-nightly
- v1.2.586-nightly
- v1.2.585-nightly
- v1.2.584-nightly
- v1.2.583-nightly
- v1.2.582-nightly
- v1.2.581-nightly
- v1.2.580-nightly
- v1.2.579-nightly
- v1.2.578-nightly
- v1.2.577-nightly
- v1.2.576-nightly
- v1.2.575-nightly
- v1.2.574-nightly
- v1.2.573-nightly
- v1.2.572-nightly
- v1.2.571-nightly
- v1.2.570-nightly
- v1.2.569-nightly
- v1.2.568-nightly
- v1.2.567-nightly
- v1.2.566-nightly
- v1.2.565-nightly
- v1.2.564-nightly
- v1.2.563-nightly
- v1.2.562-nightly
- v1.2.561-nightly
- v1.2.560-nightly
- v1.2.559-nightly
- v1.2.558-nightly
- v1.2.557-nightly
- v1.2.556-nightly
- v1.2.555-nightly
- v1.2.554-nightly
- v1.2.553-nightly
- v1.2.552-nightly
- v1.2.551-nightly
- v1.2.550-nightly
- v1.2.549-nightly
- v1.2.548-nightly
- v1.2.547-nightly
- v1.2.546-nightly
- v1.2.545-nightly
- v1.2.544-nightly
- v1.2.543-nightly
- v1.2.542-nightly
- v1.2.541-nightly
- v1.2.540-nightly
- v1.2.539-nightly
- v1.2.538-nightly
- v1.2.537-nightly
- v1.2.536-nightly
- v1.2.535-nightly
- v1.2.534-nightly
- v1.2.533-nightly
- v1.2.532-nightly
- v1.2.531-nightly
- v1.2.530
- v1.2.530-nightly
- v1.2.529-nightly
- v1.2.528-nightly
- v1.2.527-nightly
- v1.2.526-nightly
- v1.2.525-nightly
- v1.2.524-nightly
- v1.2.523-nightly
- v1.2.522-nightly
- v1.2.521-nightly
- v1.2.520-nightly
- v1.2.519-nightly
- v1.2.518-nightly
- v1.2.517-nightly
- v1.2.516-nightly
- v1.2.515-nightly
- v1.2.514-nightly
- v1.2.513-nightly
- v1.2.512-nightly
- v1.2.511-nightly
- v1.2.510-nightly
- v1.2.509-nightly
- v1.2.508-nightly
- v1.2.507-nightly
- v1.2.506-nightly
- v1.2.505-nightly
- v1.2.504-nightly
- v1.2.503-nightly
- v1.2.502-nightly
- v1.2.501-nightly
- v1.2.500-nightly
- v1.2.499-nightly
- v1.2.498-nightly
- v1.2.497-nightly
- v1.2.496-nightly
- v1.2.495-nightly
- v1.2.494-nightly
- v1.2.493-nightly
- v1.2.492-nightly
- v1.2.491-nightly
- v1.2.490-nightly
- v1.2.489-nightly
- v1.2.488-nightly
- v1.2.487-nightly
- v1.2.486-nightly
- v1.2.485-nightly
- v1.2.484-nightly
- v1.2.483-nightly
- v1.2.482-nightly
- v1.2.481-nightly
- v1.2.480-nightly
- v1.2.479-nightly
- v1.2.478-nightly
- v1.2.477-nightly
- v1.2.476-nightly
- v1.2.475-nightly
- v1.2.474-nightly
- v1.2.473-nightly
- v1.2.472-nightly
- v1.2.471-nightly
- v1.2.470-nightly
- v1.2.469-nightly
- v1.2.468-nightly
- v1.2.467-nightly
- v1.2.466-nightly
- v1.2.465-nightly
- v1.2.464-nightly
- v1.2.463-nightly
- v1.2.462-nightly
- v1.2.461-nightly
- v1.2.460-nightly
- v1.2.459-nightly
- v1.2.458-nightly
- v1.2.457-nightly
- v1.2.456-nightly
- v1.2.455-nightly
- v1.2.454-nightly
- v1.2.453
- v1.2.453-nightly
- v1.2.452
- v1.2.452-nightly
- v1.2.451-nightly
- v1.2.450-nightly
- v1.2.449-nightly
- v1.2.448-nightly
- v1.2.447-nightly
- v1.2.446-nightly
- v1.2.445-nightly
- v1.2.444-nightly
- v1.2.443-nightly
- v1.2.442-nightly
- v1.2.441-nightly
- v1.2.440-nightly
- v1.2.439-nightly
- v1.2.438-nightly
- v1.2.437-nightly
- v1.2.436-nightly
- v1.2.435-nightly
- v1.2.434-nightly
- v1.2.433-nightly
- v1.2.432-nightly
- v1.2.431-nightly
- v1.2.430-nightly
- v1.2.429-nightly
- v1.2.428-nightly
- v1.2.427-nightly
- v1.2.426-nightly
- v1.2.425-nightly
- v1.2.424-nightly
- v1.2.423-nightly
- v1.2.422-nightly
- v1.2.421-nightly
- v1.2.420-nightly
- v1.2.419-nightly
- v1.2.418-nightly
- v1.2.417-nightly
- v1.2.416-nightly
- v1.2.415-nightly
- v1.2.414-nightly
- v1.2.413-nightly
- v1.2.412-nightly
- v1.2.411-nightly
- v1.2.410
- v1.2.410-nightly
- v1.2.409-nightly
- v1.2.408-nightly
- v1.2.407-nightly
- v1.2.406-nightly
- v1.2.405-nightly
- v1.2.404-nightly
- v1.2.403-nightly
- v1.2.402-nightly
- v1.2.401-nightly
- v1.2.400-nightly
- v1.2.399-nightly
- v1.2.398-nightly
- v1.2.397-nightly
- v1.2.396-nightly
- v1.2.395-nightly
- v1.2.394-nightly
- v1.2.393-nightly
- v1.2.392-nightly
- v1.2.391-nightly
- v1.2.390-nightly
- v1.2.389-nightly
- v1.2.388-nightly
- v1.2.387-nightly
- v1.2.386-nightly
- v1.2.385-nightly
- v1.2.384-nightly
- v1.2.383-nightly
- v1.2.382-nightly
- v1.2.381-nightly
- v1.2.380-nightly
- v1.2.379-nightly
- v1.2.378-nightly
- v1.2.377-nightly
- v1.2.376-nightly
- v1.2.375-nightly
- v1.2.374-nightly
- v1.2.373-nightly
- v1.2.372-nightly
- v1.2.371
- v1.2.371-nightly
- v1.2.370-nightly
- v1.2.369-nightly
- v1.2.368-nightly
- v1.2.367-nightly
- v1.2.366-nightly
- v1.2.365-nightly
- v1.2.364-nightly
- v1.2.363-nightly
- v1.2.362-nightly
- v1.2.361-nightly
- v1.2.360-nightly
- v1.2.359-nightly
- v1.2.358-nightly
- v1.2.357-nightly
- v1.2.356-nightly
- v1.2.355-nightly
- v1.2.354-nightly
- v1.2.353-nightly
- v1.2.352-nightly
- v1.2.351-nightly
- v1.2.350-nightly
- v1.2.349-nightly
- v1.2.348-nightly
- v1.2.347-nightly
- v1.2.346-nightly
- v1.2.345-nightly
- v1.2.344
- v1.2.344-nightly
- v1.2.343-nightly
- v1.2.342-nightly
- v1.2.341-nightly
- v1.2.340-nightly
- v1.2.339-nightly
- v1.2.338-nightly
- v1.2.337-nightly
- v1.2.336-nightly
- v1.2.335-nightly
- v1.2.334-nightly
- v1.2.333-nightly
- v1.2.332-nightly
- v1.2.331-nightly
- v1.2.330-nightly
- v1.2.329-nightly
- v1.2.328-nightly
- v1.2.327-nightly
- v1.2.326-nightly
- v1.2.325-nightly
- v1.2.324-nightly
- v1.2.323-nightly
- v1.2.322-nightly
- v1.2.321-nightly
- v1.2.320-nightly
- v1.2.319-nightly
- v1.2.318-nightly
- v1.2.317-nightly
- v1.2.316-nightly
- v1.2.315-nightly
- v1.2.314-nightly
- v1.2.313-nightly
- v1.2.312-nightly
- v1.2.311-nightly
- v1.2.310-nightly
- v1.2.309-nightly
- v1.2.308-nightly
- v1.2.307
- v1.2.307-nightly
- v1.2.306-nightly
- v1.2.305-nightly
- v1.2.304-nightly
- v1.2.303-nightly
- v1.2.302-nightly
- v1.2.301-nightly
- v1.2.300-nightly
- v1.2.299-nightly
- v1.2.298-nightly
- v1.2.297-nightly
- v1.2.296-nightly
- v1.2.295-nightly
- v1.2.294-nightly
- v1.2.293-nightly
- v1.2.292
- v1.2.292-nightly
- v1.2.291-nightly
- v1.2.290
- v1.2.290-nightly
- v1.2.289-nightly
- v1.2.288-nightly
- v1.2.287-nightly
- v1.2.286-nightly
- v1.2.285-nightly
- v1.2.284-nightly
- v1.2.283-nightly
- v1.2.282-nightly
- v1.2.281-nightly
- v1.2.280-nightly
- v1.2.279
- v1.2.279-nightly
- v1.2.278-nightly
- v1.2.277-nightly
- v1.2.276-nightly
- v1.2.275
- v1.2.275-nightly
- v1.2.274-nightly
- v1.2.273-nightly
- v1.2.272-nightly
- v1.2.271-nightly
- v1.2.270-nightly
- v1.2.269-nightly
- v1.2.268-nightly
- v1.2.267-nightly
- v1.2.266-nightly
- v1.2.265-nightly
- v1.2.264-nightly
- v1.2.263-nightly
- v1.2.262
- v1.2.262-nightly
- v1.2.261-nightly
- v1.2.260-nightly
- v1.2.259-nightly
- v1.2.258-nightly
- v1.2.257-nightly
1 parent
629ee7b
commit a64551c
Showing
28 changed files
with
637 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright 2021 Datafuse Labs | ||
// | ||
// Licensed 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. | ||
|
||
use crate::Time; | ||
|
||
/// A context used when executing a [`Cmd`], to provide additional environment information. | ||
/// | ||
/// [`Cmd`]: crate::Cmd | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
pub struct CmdContext { | ||
time: Time, | ||
} | ||
|
||
impl CmdContext { | ||
pub fn from_millis(millis: u64) -> Self { | ||
Self::new(Time::from_millis(millis)) | ||
} | ||
|
||
pub fn new(time: Time) -> Self { | ||
CmdContext { time } | ||
} | ||
|
||
/// Returns the time since 1970-01-01 when this log is proposed by the leader. | ||
pub fn time(&self) -> Time { | ||
self.time | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright 2021 Datafuse Labs | ||
// | ||
// Licensed 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. | ||
|
||
use std::time::Duration; | ||
|
||
use crate::cmd::CmdContext; | ||
use crate::seq_value::KVMeta; | ||
use crate::time::Interval; | ||
|
||
/// Specifies the metadata associated with a kv record, used in an `upsert` cmd. | ||
/// | ||
/// This is similar to [`KVMeta`] but differs, [`KVMeta`] is used in storage, | ||
/// as this instance is employed for transport purposes. | ||
/// When an `upsert` cmd is applied, this instance is evaluated and a `KVMeta` is built. | ||
#[derive(serde::Serialize, serde::Deserialize, Debug, Default, Clone, Eq, PartialEq)] | ||
pub struct MetaSpec { | ||
/// expiration time in second since 1970 | ||
pub(crate) expire_at: Option<u64>, | ||
|
||
/// Relative expiration time interval since when the raft log is applied. | ||
/// | ||
/// Use this field if possible to avoid the clock skew between client and meta-service. | ||
/// `expire_at` may already be expired when it is applied to state machine. | ||
/// | ||
/// If it is not None, once applied, the `expire_at` field will be replaced with the calculated absolute expiration time. | ||
/// | ||
/// For backward compatibility, this field is not serialized if it `None`, as if it does not exist. | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub(crate) ttl: Option<Interval>, | ||
} | ||
|
||
impl MetaSpec { | ||
/// Create a new KVMeta | ||
pub fn new(expire_at: Option<u64>, ttl: Option<Interval>) -> Self { | ||
Self { expire_at, ttl } | ||
} | ||
|
||
/// Create a KVMeta with a absolute expiration time in second since 1970-01-01. | ||
pub fn new_expire(expire_at_sec: u64) -> Self { | ||
Self { | ||
expire_at: Some(expire_at_sec), | ||
ttl: None, | ||
} | ||
} | ||
|
||
/// Create a KVMeta with relative expiration time(ttl). | ||
pub fn new_ttl(ttl: Duration) -> Self { | ||
Self { | ||
expire_at: None, | ||
ttl: Some(Interval::from_duration(ttl)), | ||
} | ||
} | ||
|
||
/// Convert meta spec into a [`KVMeta`] to be stored in storage. | ||
pub fn to_kv_meta(&self, cmd_ctx: &CmdContext) -> KVMeta { | ||
// If `ttl` is set, override `expire_at` | ||
if let Some(ttl) = self.ttl { | ||
return KVMeta::new_expire((cmd_ctx.time() + ttl).seconds()); | ||
} | ||
|
||
// No `ttl`, check if absolute expire time `expire_at` is set. | ||
KVMeta::new(self.expire_at) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use std::time::Duration; | ||
|
||
use super::MetaSpec; | ||
use crate::cmd::CmdContext; | ||
use crate::KVMeta; | ||
use crate::Time; | ||
|
||
#[test] | ||
fn test_serde() { | ||
let meta = MetaSpec::new_expire(100); | ||
let s = serde_json::to_string(&meta).unwrap(); | ||
assert_eq!(r#"{"expire_at":100}"#, s); | ||
|
||
let got: KVMeta = serde_json::from_str(&s).unwrap(); | ||
assert_eq!(Some(100), got.expire_at); | ||
|
||
let meta = MetaSpec::new_ttl(Duration::from_millis(100)); | ||
let s = serde_json::to_string(&meta).unwrap(); | ||
assert_eq!(r#"{"expire_at":null,"ttl":{"millis":100}}"#, s); | ||
} | ||
|
||
#[test] | ||
fn test_to_kv_meta() { | ||
let cmd_ctx = CmdContext::new(Time::from_millis(2000)); | ||
|
||
// ttl | ||
let meta = MetaSpec::new_ttl(Duration::from_millis(1000)); | ||
let kv_meta = meta.to_kv_meta(&cmd_ctx); | ||
assert_eq!(kv_meta.get_expire_at_ms().unwrap(), 3000); | ||
|
||
// expire_at | ||
let meta = MetaSpec::new_expire(5); | ||
let kv_meta = meta.to_kv_meta(&cmd_ctx); | ||
assert_eq!(kv_meta.get_expire_at_ms().unwrap(), 5_000); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright 2021 Datafuse Labs | ||
// | ||
// Licensed 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. | ||
|
||
/// Evaluate and returns the absolute expire time. | ||
pub trait EvalExpireTime { | ||
/// Evaluate and returns the absolute expire time in millisecond since 1970. | ||
/// | ||
/// If there is no expire time, return u64::MAX. | ||
fn eval_expire_at_ms(&self) -> u64; | ||
} | ||
|
||
impl<T> EvalExpireTime for &T | ||
where T: EvalExpireTime | ||
{ | ||
fn eval_expire_at_ms(&self) -> u64 { | ||
EvalExpireTime::eval_expire_at_ms(*self) | ||
} | ||
} | ||
|
||
impl<T> EvalExpireTime for Option<T> | ||
where T: EvalExpireTime | ||
{ | ||
fn eval_expire_at_ms(&self) -> u64 { | ||
self.as_ref() | ||
.map(|m| m.eval_expire_at_ms()) | ||
.unwrap_or(u64::MAX) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
// Copyright 2021 Datafuse Labs | ||
// | ||
// Licensed 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. | ||
|
||
use std::ops::Add; | ||
use std::ops::Sub; | ||
use std::time::Duration; | ||
|
||
/// A interval of time. | ||
/// | ||
/// As a replacement of [`Duration`], which is not `serde`-able. | ||
/// | ||
/// `Interval` implements: `Interval +- Interval`. | ||
#[derive( | ||
serde::Serialize, | ||
serde::Deserialize, | ||
Debug, | ||
Default, | ||
Clone, | ||
Copy, | ||
Hash, | ||
Eq, | ||
PartialEq, | ||
PartialOrd, | ||
Ord, | ||
)] | ||
pub struct Interval { | ||
pub(crate) millis: u64, | ||
} | ||
|
||
impl Interval { | ||
pub fn from_duration(duration: Duration) -> Self { | ||
Self { | ||
millis: duration.as_millis() as u64, | ||
} | ||
} | ||
|
||
pub fn from_millis(millis: u64) -> Self { | ||
Self::from_duration(Duration::from_millis(millis)) | ||
} | ||
|
||
pub fn from_secs(secs: u64) -> Self { | ||
Self::from_duration(Duration::from_secs(secs)) | ||
} | ||
|
||
pub fn millis(&self) -> u64 { | ||
self.millis | ||
} | ||
|
||
pub fn seconds(&self) -> u64 { | ||
self.millis / 1000 | ||
} | ||
} | ||
|
||
impl Add for Interval { | ||
type Output = Self; | ||
|
||
fn add(self, rhs: Self) -> Self::Output { | ||
Self { | ||
millis: self.millis.saturating_add(rhs.millis), | ||
} | ||
} | ||
} | ||
|
||
impl Sub for Interval { | ||
type Output = Self; | ||
|
||
fn sub(self, rhs: Self) -> Self::Output { | ||
Self { | ||
millis: self.millis.saturating_sub(rhs.millis), | ||
} | ||
} | ||
} | ||
|
||
/// A time point since 1970-01-01. | ||
/// | ||
/// As a replacement of [`Instant`](std::time::Instant), which is not `serde`-able. | ||
/// `Time` implements: `Time +- Interval = Time` and `Time - Time = Interval`. | ||
#[derive( | ||
serde::Serialize, | ||
serde::Deserialize, | ||
Debug, | ||
Default, | ||
Clone, | ||
Copy, | ||
Hash, | ||
Eq, | ||
PartialEq, | ||
PartialOrd, | ||
Ord, | ||
)] | ||
pub struct Time { | ||
pub(crate) time: Interval, | ||
} | ||
|
||
impl Time { | ||
pub fn from_millis(millis: u64) -> Self { | ||
Self { | ||
time: Interval::from_millis(millis), | ||
} | ||
} | ||
|
||
pub fn from_secs(secs: u64) -> Self { | ||
Self { | ||
time: Interval::from_secs(secs), | ||
} | ||
} | ||
|
||
pub fn millis(&self) -> u64 { | ||
self.time.millis() | ||
} | ||
|
||
pub fn seconds(&self) -> u64 { | ||
self.time.seconds() | ||
} | ||
} | ||
|
||
impl Add<Interval> for Time { | ||
type Output = Self; | ||
|
||
fn add(self, rhs: Interval) -> Self::Output { | ||
Self { | ||
time: self.time + rhs, | ||
} | ||
} | ||
} | ||
|
||
impl Sub<Interval> for Time { | ||
type Output = Self; | ||
|
||
fn sub(self, rhs: Interval) -> Self::Output { | ||
Self { | ||
time: self.time - rhs, | ||
} | ||
} | ||
} | ||
|
||
impl Sub for Time { | ||
type Output = Interval; | ||
|
||
fn sub(self, rhs: Self) -> Self::Output { | ||
self.time - rhs.time | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::Interval; | ||
use crate::time::Time; | ||
|
||
#[test] | ||
fn test_interval() { | ||
let interval = Interval::from_millis(1000); | ||
assert_eq!(interval.millis(), 1000); | ||
assert_eq!(interval.seconds(), 1); | ||
|
||
let interval = Interval::from_secs(1); | ||
assert_eq!(interval.millis(), 1000); | ||
assert_eq!(interval.seconds(), 1); | ||
|
||
assert_eq!(interval + interval, Interval::from_millis(2000)); | ||
assert_eq!(interval - interval, Interval::from_millis(0)); | ||
assert_eq!( | ||
interval - Interval::from_millis(1500), | ||
Interval::from_millis(0) | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_time() { | ||
let time = Time::from_millis(1000); | ||
assert_eq!(time.millis(), 1000); | ||
assert_eq!(time.seconds(), 1); | ||
|
||
let time = Time::from_secs(1); | ||
assert_eq!(time.millis(), 1000); | ||
assert_eq!(time.seconds(), 1); | ||
|
||
assert_eq!(time + Interval::from_millis(1000), Time::from_millis(2000)); | ||
assert_eq!(time - Interval::from_millis(500), Time::from_millis(500)); | ||
assert_eq!(time - Time::from_millis(500), Interval::from_millis(500)); | ||
assert_eq!(time - Time::from_millis(1500), Interval::from_millis(0)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters