Skip to main content

mz_storage_types/
instances.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! Types related to storage instances.
11
12use std::fmt;
13use std::str::FromStr;
14
15use anyhow::bail;
16use serde::{Deserialize, Serialize};
17use tracing::error;
18
19/// Identifier of a storage instance.
20#[derive(
21    Clone,
22    Copy,
23    Debug,
24    Eq,
25    PartialEq,
26    Ord,
27    PartialOrd,
28    Hash,
29    Serialize,
30    Deserialize
31)]
32pub enum StorageInstanceId {
33    /// A system storage instance.
34    System(u64),
35    /// A user storage instance.
36    User(u64),
37}
38
39impl StorageInstanceId {
40    /// Creates a new `StorageInstanceId` in the system namespace. The top 16 bits of `id` must be
41    /// 0, because this ID is packed into 48 bits of
42    /// [`mz_repr::GlobalId::IntrospectionSourceIndex`].
43    pub fn system(id: u64) -> Option<Self> {
44        Self::new(id, Self::System)
45    }
46
47    /// Creates a new `StorageInstanceId` in the user namespace. The top 16 bits of `id` must be
48    /// 0, because this ID is packed into 48 bits of
49    /// [`mz_repr::GlobalId::IntrospectionSourceIndex`].
50    pub fn user(id: u64) -> Option<Self> {
51        Self::new(id, Self::User)
52    }
53
54    fn new(id: u64, variant: fn(u64) -> Self) -> Option<Self> {
55        const MASK: u64 = 0xFFFF << 48;
56        const WARN_MASK: u64 = 1 << 47;
57        if MASK & id == 0 {
58            if WARN_MASK & id != 0 {
59                error!("{WARN_MASK} or more `StorageInstanceId`s allocated, we will run out soon");
60            }
61            Some(variant(id))
62        } else {
63            None
64        }
65    }
66
67    pub fn inner_id(&self) -> u64 {
68        match self {
69            StorageInstanceId::System(id) | StorageInstanceId::User(id) => *id,
70        }
71    }
72
73    pub fn is_user(&self) -> bool {
74        matches!(self, Self::User(_))
75    }
76
77    pub fn is_system(&self) -> bool {
78        matches!(self, Self::System(_))
79    }
80}
81
82impl FromStr for StorageInstanceId {
83    type Err = anyhow::Error;
84
85    fn from_str(s: &str) -> Result<Self, Self::Err> {
86        if s.len() < 2 {
87            bail!("couldn't parse compute instance id {}", s);
88        }
89        let val: u64 = s[1..].parse()?;
90        match s.chars().next().unwrap() {
91            's' => Ok(Self::System(val)),
92            'u' => Ok(Self::User(val)),
93            _ => bail!("couldn't parse compute instance id {}", s),
94        }
95    }
96}
97
98impl fmt::Display for StorageInstanceId {
99    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100        match self {
101            Self::System(id) => write!(f, "s{}", id),
102            Self::User(id) => write!(f, "u{}", id),
103        }
104    }
105}