From c2a1e01208b5ea535f6a4e64a82db7c70e30af41 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 31 Jan 2023 13:51:10 +0200 Subject: [PATCH] Code review: Move Key into pageserver model and use it in HTTP responses --- libs/pageserver_api/src/models.rs | 180 +++++++++++++++++- pageserver/benches/bench_layer_map.rs | 5 +- pageserver/benches/bench_walredo.rs | 2 +- pageserver/src/bin/draw_timeline_dir.rs | 2 +- pageserver/src/keyspace.rs | 2 +- pageserver/src/page_cache.rs | 2 +- pageserver/src/pgdatadir_mapping.rs | 5 +- pageserver/src/repository.rs | 170 +---------------- pageserver/src/tenant.rs | 5 +- pageserver/src/tenant/layer_map.rs | 2 +- pageserver/src/tenant/storage_layer.rs | 4 +- .../src/tenant/storage_layer/delta_layer.rs | 8 +- .../src/tenant/storage_layer/filename.rs | 2 +- .../src/tenant/storage_layer/image_layer.rs | 7 +- .../tenant/storage_layer/inmemory_layer.rs | 4 +- .../src/tenant/storage_layer/remote_layer.rs | 11 +- pageserver/src/tenant/timeline.rs | 4 +- pageserver/src/walredo.rs | 4 +- 18 files changed, 210 insertions(+), 209 deletions(-) diff --git a/libs/pageserver_api/src/models.rs b/libs/pageserver_api/src/models.rs index e1c4216023..b4f08f2923 100644 --- a/libs/pageserver_api/src/models.rs +++ b/libs/pageserver_api/src/models.rs @@ -1,9 +1,11 @@ use std::{ collections::BTreeSet, + fmt, num::{NonZeroU64, NonZeroUsize}, + ops::Range, }; -use byteorder::{BigEndian, ReadBytesExt}; +use byteorder::{BigEndian, ByteOrder, ReadBytesExt, BE}; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; use utils::{ @@ -12,7 +14,6 @@ use utils::{ }; use crate::reltag::RelTag; -use anyhow::bail; use bytes::{BufMut, Bytes, BytesMut}; /// A state of a tenant in pageserver's memory. @@ -248,16 +249,16 @@ pub enum InMemoryLayerInfo { pub enum HistoricLayerInfo { Delta { layer_file_name: String, - key_start: String, - key_end: String, + key_start: Key, + key_end: Key, lsn_start: Lsn, lsn_end: Lsn, remote: bool, }, Image { layer_file_name: String, - key_start: String, - key_end: String, + key_start: Key, + key_end: Key, lsn_start: Lsn, remote: bool, }, @@ -466,7 +467,7 @@ impl PagestreamFeMessage { lsn: Lsn::from(body.read_u64::()?), dbnode: body.read_u32::()?, })), - _ => bail!("unknown smgr message tag: {:?}", msg_tag), + _ => anyhow::bail!("unknown smgr message tag: {msg_tag:?}"), } } } @@ -506,6 +507,171 @@ impl PagestreamBeMessage { } } +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)] +/// Key used in the Repository kv-store. +/// +/// The Repository treats this as an opaque struct, but see the code in pgdatadir_mapping.rs +/// for what we actually store in these fields. +pub struct Key { + pub field1: u8, + pub field2: u32, + pub field3: u32, + pub field4: u32, + pub field5: u8, + pub field6: u32, +} + +pub const KEY_SIZE: usize = 18; + +impl Key { + /// 'field2' is used to store tablespaceid for relations and small enum numbers for other relish. + /// As long as Neon does not support tablespace (because of lack of access to local file system), + /// we can assume that only some predefined namespace OIDs are used which can fit in u16 + pub fn to_i128(&self) -> i128 { + assert!(self.field2 < 0xFFFF || self.field2 == 0xFFFFFFFF || self.field2 == 0x22222222); + (((self.field1 & 0xf) as i128) << 120) + | (((self.field2 & 0xFFFF) as i128) << 104) + | ((self.field3 as i128) << 72) + | ((self.field4 as i128) << 40) + | ((self.field5 as i128) << 32) + | self.field6 as i128 + } + + pub fn from_i128(x: i128) -> Self { + Key { + field1: ((x >> 120) & 0xf) as u8, + field2: ((x >> 104) & 0xFFFF) as u32, + field3: (x >> 72) as u32, + field4: (x >> 40) as u32, + field5: (x >> 32) as u8, + field6: x as u32, + } + } + + pub fn next(&self) -> Key { + self.add(1) + } + + pub fn add(&self, x: u32) -> Key { + let mut key = *self; + + let r = key.field6.overflowing_add(x); + key.field6 = r.0; + if r.1 { + let r = key.field5.overflowing_add(1); + key.field5 = r.0; + if r.1 { + let r = key.field4.overflowing_add(1); + key.field4 = r.0; + if r.1 { + let r = key.field3.overflowing_add(1); + key.field3 = r.0; + if r.1 { + let r = key.field2.overflowing_add(1); + key.field2 = r.0; + if r.1 { + let r = key.field1.overflowing_add(1); + key.field1 = r.0; + assert!(!r.1); + } + } + } + } + } + key + } + + pub fn from_slice(b: &[u8]) -> Self { + Key { + field1: b[0], + field2: u32::from_be_bytes(b[1..5].try_into().unwrap()), + field3: u32::from_be_bytes(b[5..9].try_into().unwrap()), + field4: u32::from_be_bytes(b[9..13].try_into().unwrap()), + field5: b[13], + field6: u32::from_be_bytes(b[14..18].try_into().unwrap()), + } + } + + pub fn write_to_byte_slice(&self, buf: &mut [u8]) { + buf[0] = self.field1; + BE::write_u32(&mut buf[1..5], self.field2); + BE::write_u32(&mut buf[5..9], self.field3); + BE::write_u32(&mut buf[9..13], self.field4); + buf[13] = self.field5; + BE::write_u32(&mut buf[14..18], self.field6); + } +} + +pub fn key_range_size(key_range: &Range) -> u32 { + let start = key_range.start; + let end = key_range.end; + + if end.field1 != start.field1 + || end.field2 != start.field2 + || end.field3 != start.field3 + || end.field4 != start.field4 + { + return u32::MAX; + } + + let start = (start.field5 as u64) << 32 | start.field6 as u64; + let end = (end.field5 as u64) << 32 | end.field6 as u64; + + let diff = end - start; + if diff > u32::MAX as u64 { + u32::MAX + } else { + diff as u32 + } +} + +pub fn singleton_range(key: Key) -> Range { + key..key.next() +} + +impl fmt::Display for Key { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{:02X}{:08X}{:08X}{:08X}{:02X}{:08X}", + self.field1, self.field2, self.field3, self.field4, self.field5, self.field6 + ) + } +} + +impl Key { + pub const MIN: Key = Key { + field1: u8::MIN, + field2: u32::MIN, + field3: u32::MIN, + field4: u32::MIN, + field5: u8::MIN, + field6: u32::MIN, + }; + pub const MAX: Key = Key { + field1: u8::MAX, + field2: u32::MAX, + field3: u32::MAX, + field4: u32::MAX, + field5: u8::MAX, + field6: u32::MAX, + }; + + pub fn from_hex(s: &str) -> anyhow::Result { + if s.len() != 36 { + anyhow::bail!("parse error"); + } + Ok(Key { + field1: u8::from_str_radix(&s[0..2], 16)?, + field2: u32::from_str_radix(&s[2..10], 16)?, + field3: u32::from_str_radix(&s[10..18], 16)?, + field4: u32::from_str_radix(&s[18..26], 16)?, + field5: u8::from_str_radix(&s[26..28], 16)?, + field6: u32::from_str_radix(&s[28..36], 16)?, + }) + } +} + #[cfg(test)] mod tests { use bytes::Buf; diff --git a/pageserver/benches/bench_layer_map.rs b/pageserver/benches/bench_layer_map.rs index e18c00da96..93e0127eb9 100644 --- a/pageserver/benches/bench_layer_map.rs +++ b/pageserver/benches/bench_layer_map.rs @@ -1,9 +1,10 @@ use pageserver::keyspace::{KeyPartitioning, KeySpace}; -use pageserver::repository::Key; use pageserver::tenant::layer_map::LayerMap; use pageserver::tenant::storage_layer::Layer; use pageserver::tenant::storage_layer::{DeltaFileName, ImageFileName, LayerDescriptor}; -use rand::prelude::{SeedableRng, SliceRandom, StdRng}; +use pageserver_api::models::Key; +use rand::prelude::{SeedableRng, StdRng}; +use rand::seq::SliceRandom; use std::cmp::{max, min}; use std::fs::File; use std::io::{BufRead, BufReader}; diff --git a/pageserver/benches/bench_walredo.rs b/pageserver/benches/bench_walredo.rs index 49216c68f1..b4a0643cbe 100644 --- a/pageserver/benches/bench_walredo.rs +++ b/pageserver/benches/bench_walredo.rs @@ -12,10 +12,10 @@ use std::sync::{Arc, Barrier}; use bytes::{Buf, Bytes}; use pageserver::{ config::PageServerConf, - repository::Key, walrecord::NeonWalRecord, walredo::{PostgresRedoManager, WalRedoError}, }; +use pageserver_api::models::Key; use utils::{id::TenantId, lsn::Lsn}; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; diff --git a/pageserver/src/bin/draw_timeline_dir.rs b/pageserver/src/bin/draw_timeline_dir.rs index da13ee452c..4bd3e5838a 100644 --- a/pageserver/src/bin/draw_timeline_dir.rs +++ b/pageserver/src/bin/draw_timeline_dir.rs @@ -22,7 +22,7 @@ //! TODO Consider shipping this as a grafana panel plugin: //! https://grafana.com/tutorials/build-a-panel-plugin/ use anyhow::Result; -use pageserver::repository::Key; +use pageserver_api::models::Key; use std::cmp::Ordering; use std::io::{self, BufRead}; use std::path::PathBuf; diff --git a/pageserver/src/keyspace.rs b/pageserver/src/keyspace.rs index 64024a2d8d..2d68b48d15 100644 --- a/pageserver/src/keyspace.rs +++ b/pageserver/src/keyspace.rs @@ -1,4 +1,4 @@ -use crate::repository::{key_range_size, singleton_range, Key}; +use pageserver_api::models::{key_range_size, singleton_range, Key}; use postgres_ffi::BLCKSZ; use std::ops::Range; diff --git a/pageserver/src/page_cache.rs b/pageserver/src/page_cache.rs index d2fe06697e..bf2e9bdcb6 100644 --- a/pageserver/src/page_cache.rs +++ b/pageserver/src/page_cache.rs @@ -47,13 +47,13 @@ use std::{ use anyhow::Context; use once_cell::sync::OnceCell; +use pageserver_api::models::Key; use tracing::error; use utils::{ id::{TenantId, TimelineId}, lsn::Lsn, }; -use crate::repository::Key; use crate::tenant::writeback_ephemeral_file; static PAGE_CACHE: OnceCell = OnceCell::new(); diff --git a/pageserver/src/pgdatadir_mapping.rs b/pageserver/src/pgdatadir_mapping.rs index 6f9035305d..c8888129e2 100644 --- a/pageserver/src/pgdatadir_mapping.rs +++ b/pageserver/src/pgdatadir_mapping.rs @@ -13,7 +13,10 @@ use crate::repository::*; use crate::walrecord::NeonWalRecord; use anyhow::Context; use bytes::{Buf, Bytes}; -use pageserver_api::reltag::{RelTag, SlruKind}; +use pageserver_api::{ + models::Key, + reltag::{RelTag, SlruKind}, +}; use postgres_ffi::relfile_utils::{FSM_FORKNUM, VISIBILITYMAP_FORKNUM}; use postgres_ffi::BLCKSZ; use postgres_ffi::{Oid, TimestampTz, TransactionId}; diff --git a/pageserver/src/repository.rs b/pageserver/src/repository.rs index 092503b7c5..ea1a2c92fd 100644 --- a/pageserver/src/repository.rs +++ b/pageserver/src/repository.rs @@ -1,177 +1,9 @@ use crate::walrecord::NeonWalRecord; -use anyhow::{bail, Result}; -use byteorder::{ByteOrder, BE}; use bytes::Bytes; use serde::{Deserialize, Serialize}; -use std::fmt; -use std::ops::{AddAssign, Range}; +use std::ops::AddAssign; use std::time::Duration; -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)] -/// Key used in the Repository kv-store. -/// -/// The Repository treats this as an opaque struct, but see the code in pgdatadir_mapping.rs -/// for what we actually store in these fields. -pub struct Key { - pub field1: u8, - pub field2: u32, - pub field3: u32, - pub field4: u32, - pub field5: u8, - pub field6: u32, -} - -pub const KEY_SIZE: usize = 18; - -impl Key { - /// 'field2' is used to store tablespaceid for relations and small enum numbers for other relish. - /// As long as Neon does not support tablespace (because of lack of access to local file system), - /// we can assume that only some predefined namespace OIDs are used which can fit in u16 - pub fn to_i128(&self) -> i128 { - assert!(self.field2 < 0xFFFF || self.field2 == 0xFFFFFFFF || self.field2 == 0x22222222); - (((self.field1 & 0xf) as i128) << 120) - | (((self.field2 & 0xFFFF) as i128) << 104) - | ((self.field3 as i128) << 72) - | ((self.field4 as i128) << 40) - | ((self.field5 as i128) << 32) - | self.field6 as i128 - } - - pub fn from_i128(x: i128) -> Self { - Key { - field1: ((x >> 120) & 0xf) as u8, - field2: ((x >> 104) & 0xFFFF) as u32, - field3: (x >> 72) as u32, - field4: (x >> 40) as u32, - field5: (x >> 32) as u8, - field6: x as u32, - } - } - - pub fn next(&self) -> Key { - self.add(1) - } - - pub fn add(&self, x: u32) -> Key { - let mut key = *self; - - let r = key.field6.overflowing_add(x); - key.field6 = r.0; - if r.1 { - let r = key.field5.overflowing_add(1); - key.field5 = r.0; - if r.1 { - let r = key.field4.overflowing_add(1); - key.field4 = r.0; - if r.1 { - let r = key.field3.overflowing_add(1); - key.field3 = r.0; - if r.1 { - let r = key.field2.overflowing_add(1); - key.field2 = r.0; - if r.1 { - let r = key.field1.overflowing_add(1); - key.field1 = r.0; - assert!(!r.1); - } - } - } - } - } - key - } - - pub fn from_slice(b: &[u8]) -> Self { - Key { - field1: b[0], - field2: u32::from_be_bytes(b[1..5].try_into().unwrap()), - field3: u32::from_be_bytes(b[5..9].try_into().unwrap()), - field4: u32::from_be_bytes(b[9..13].try_into().unwrap()), - field5: b[13], - field6: u32::from_be_bytes(b[14..18].try_into().unwrap()), - } - } - - pub fn write_to_byte_slice(&self, buf: &mut [u8]) { - buf[0] = self.field1; - BE::write_u32(&mut buf[1..5], self.field2); - BE::write_u32(&mut buf[5..9], self.field3); - BE::write_u32(&mut buf[9..13], self.field4); - buf[13] = self.field5; - BE::write_u32(&mut buf[14..18], self.field6); - } -} - -pub fn key_range_size(key_range: &Range) -> u32 { - let start = key_range.start; - let end = key_range.end; - - if end.field1 != start.field1 - || end.field2 != start.field2 - || end.field3 != start.field3 - || end.field4 != start.field4 - { - return u32::MAX; - } - - let start = (start.field5 as u64) << 32 | start.field6 as u64; - let end = (end.field5 as u64) << 32 | end.field6 as u64; - - let diff = end - start; - if diff > u32::MAX as u64 { - u32::MAX - } else { - diff as u32 - } -} - -pub fn singleton_range(key: Key) -> Range { - key..key.next() -} - -impl fmt::Display for Key { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{:02X}{:08X}{:08X}{:08X}{:02X}{:08X}", - self.field1, self.field2, self.field3, self.field4, self.field5, self.field6 - ) - } -} - -impl Key { - pub const MIN: Key = Key { - field1: u8::MIN, - field2: u32::MIN, - field3: u32::MIN, - field4: u32::MIN, - field5: u8::MIN, - field6: u32::MIN, - }; - pub const MAX: Key = Key { - field1: u8::MAX, - field2: u32::MAX, - field3: u32::MAX, - field4: u32::MAX, - field5: u8::MAX, - field6: u32::MAX, - }; - - pub fn from_hex(s: &str) -> Result { - if s.len() != 36 { - bail!("parse error"); - } - Ok(Key { - field1: u8::from_str_radix(&s[0..2], 16)?, - field2: u32::from_str_radix(&s[2..10], 16)?, - field3: u32::from_str_radix(&s[10..18], 16)?, - field4: u32::from_str_radix(&s[18..26], 16)?, - field5: u8::from_str_radix(&s[26..28], 16)?, - field6: u32::from_str_radix(&s[28..36], 16)?, - }) - } -} - /// A 'value' stored for a one Key. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Value { diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 9fb540cfae..a649e81d7a 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -2686,6 +2686,7 @@ pub mod harness { use bytes::{Bytes, BytesMut}; use once_cell::sync::Lazy; use once_cell::sync::OnceCell; + use pageserver_api::models::Key; use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::{fs, path::PathBuf}; use utils::logging; @@ -2693,7 +2694,6 @@ pub mod harness { use crate::{ config::PageServerConf, - repository::Key, tenant::Tenant, walrecord::NeonWalRecord, walredo::{WalRedoError, WalRedoManager}, @@ -2882,13 +2882,14 @@ pub mod harness { mod tests { use super::*; use crate::keyspace::KeySpaceAccum; - use crate::repository::{Key, Value}; + use crate::repository::Value; use crate::tenant::harness::*; use crate::DEFAULT_PG_VERSION; use crate::METADATA_FILE_NAME; use bytes::BytesMut; use hex_literal::hex; use once_cell::sync::Lazy; + use pageserver_api::models::Key; use rand::{thread_rng, Rng}; static TEST_KEY: Lazy = diff --git a/pageserver/src/tenant/layer_map.rs b/pageserver/src/tenant/layer_map.rs index ed1a32c8fd..846c83582e 100644 --- a/pageserver/src/tenant/layer_map.rs +++ b/pageserver/src/tenant/layer_map.rs @@ -48,10 +48,10 @@ mod layer_coverage; use crate::keyspace::KeyPartitioning; use crate::metrics::NUM_ONDISK_LAYERS; -use crate::repository::Key; use crate::tenant::storage_layer::InMemoryLayer; use crate::tenant::storage_layer::Layer; use anyhow::Result; +use pageserver_api::models::Key; use std::collections::VecDeque; use std::ops::Range; use std::sync::Arc; diff --git a/pageserver/src/tenant/storage_layer.rs b/pageserver/src/tenant/storage_layer.rs index e20263ee0a..4125a3ed68 100644 --- a/pageserver/src/tenant/storage_layer.rs +++ b/pageserver/src/tenant/storage_layer.rs @@ -6,11 +6,11 @@ mod image_layer; mod inmemory_layer; mod remote_layer; -use crate::repository::{Key, Value}; +use crate::repository::Value; use crate::walrecord::NeonWalRecord; use anyhow::Result; use bytes::Bytes; -use pageserver_api::models::HistoricLayerInfo; +use pageserver_api::models::{HistoricLayerInfo, Key}; use std::ops::Range; use std::path::PathBuf; use std::sync::Arc; diff --git a/pageserver/src/tenant/storage_layer/delta_layer.rs b/pageserver/src/tenant/storage_layer/delta_layer.rs index 54f627d4c5..102f1df18f 100644 --- a/pageserver/src/tenant/storage_layer/delta_layer.rs +++ b/pageserver/src/tenant/storage_layer/delta_layer.rs @@ -25,7 +25,7 @@ //! use crate::config::PageServerConf; use crate::page_cache::{PageReadGuard, PAGE_SZ}; -use crate::repository::{Key, Value, KEY_SIZE}; +use crate::repository::Value; use crate::tenant::blob_io::{BlobCursor, BlobWriter, WriteBlobWriter}; use crate::tenant::block_io::{BlockBuf, BlockCursor, BlockReader, FileBlockReader}; use crate::tenant::disk_btree::{DiskBtreeBuilder, DiskBtreeReader, VisitDirection}; @@ -36,7 +36,7 @@ use crate::virtual_file::VirtualFile; use crate::{walrecord, TEMP_FILE_SUFFIX}; use crate::{DELTA_FILE_MAGIC, STORAGE_FORMAT_VERSION}; use anyhow::{bail, ensure, Context, Result}; -use pageserver_api::models::HistoricLayerInfo; +use pageserver_api::models::{HistoricLayerInfo, Key, KEY_SIZE}; use rand::{distributions::Alphanumeric, Rng}; use serde::{Deserialize, Serialize}; use std::fs::{self, File}; @@ -424,8 +424,8 @@ impl PersistentLayer for DeltaLayer { HistoricLayerInfo::Delta { layer_file_name, - key_start: key_range.start.to_string(), - key_end: key_range.end.to_string(), + key_start: key_range.start, + key_end: key_range.end, lsn_start: lsn_range.start, lsn_end: lsn_range.end, remote: false, diff --git a/pageserver/src/tenant/storage_layer/filename.rs b/pageserver/src/tenant/storage_layer/filename.rs index 6ecf9227c7..ade2fc20ab 100644 --- a/pageserver/src/tenant/storage_layer/filename.rs +++ b/pageserver/src/tenant/storage_layer/filename.rs @@ -2,13 +2,13 @@ //! Helper functions for dealing with filenames of the image and delta layer files. //! use crate::config::PageServerConf; -use crate::repository::Key; use std::cmp::Ordering; use std::fmt; use std::ops::Range; use std::path::PathBuf; use std::str::FromStr; +use pageserver_api::models::Key; use utils::lsn::Lsn; // Note: Timeline::load_layer_map() relies on this sort order diff --git a/pageserver/src/tenant/storage_layer/image_layer.rs b/pageserver/src/tenant/storage_layer/image_layer.rs index 52748a77de..326c20c713 100644 --- a/pageserver/src/tenant/storage_layer/image_layer.rs +++ b/pageserver/src/tenant/storage_layer/image_layer.rs @@ -21,7 +21,6 @@ //! actual page images are stored in the "values" part. use crate::config::PageServerConf; use crate::page_cache::PAGE_SZ; -use crate::repository::{Key, KEY_SIZE}; use crate::tenant::blob_io::{BlobCursor, BlobWriter, WriteBlobWriter}; use crate::tenant::block_io::{BlockBuf, BlockReader, FileBlockReader}; use crate::tenant::disk_btree::{DiskBtreeBuilder, DiskBtreeReader, VisitDirection}; @@ -33,7 +32,7 @@ use crate::{IMAGE_FILE_MAGIC, STORAGE_FORMAT_VERSION, TEMP_FILE_SUFFIX}; use anyhow::{bail, ensure, Context, Result}; use bytes::Bytes; use hex; -use pageserver_api::models::HistoricLayerInfo; +use pageserver_api::models::{HistoricLayerInfo, Key, KEY_SIZE}; use rand::{distributions::Alphanumeric, Rng}; use serde::{Deserialize, Serialize}; use std::fs::{self, File}; @@ -242,8 +241,8 @@ impl PersistentLayer for ImageLayer { HistoricLayerInfo::Image { layer_file_name, - key_start: key_range.start.to_string(), - key_end: key_range.end.to_string(), + key_start: key_range.start, + key_end: key_range.end, lsn_start: lsn_range.start, remote: false, } diff --git a/pageserver/src/tenant/storage_layer/inmemory_layer.rs b/pageserver/src/tenant/storage_layer/inmemory_layer.rs index c2a04d8ec9..a4db803ead 100644 --- a/pageserver/src/tenant/storage_layer/inmemory_layer.rs +++ b/pageserver/src/tenant/storage_layer/inmemory_layer.rs @@ -5,14 +5,14 @@ //! its position in the file, is kept in memory, though. //! use crate::config::PageServerConf; -use crate::repository::{Key, Value}; +use crate::repository::Value; use crate::tenant::blob_io::{BlobCursor, BlobWriter}; use crate::tenant::block_io::BlockReader; use crate::tenant::ephemeral_file::EphemeralFile; use crate::tenant::storage_layer::{ValueReconstructResult, ValueReconstructState}; use crate::walrecord; use anyhow::{ensure, Result}; -use pageserver_api::models::InMemoryLayerInfo; +use pageserver_api::models::{InMemoryLayerInfo, Key}; use std::cell::RefCell; use std::collections::HashMap; use tracing::*; diff --git a/pageserver/src/tenant/storage_layer/remote_layer.rs b/pageserver/src/tenant/storage_layer/remote_layer.rs index 90eff9ef9c..f67f3dc3cf 100644 --- a/pageserver/src/tenant/storage_layer/remote_layer.rs +++ b/pageserver/src/tenant/storage_layer/remote_layer.rs @@ -2,11 +2,10 @@ //! in remote storage. //! use crate::config::PageServerConf; -use crate::repository::Key; use crate::tenant::remote_timeline_client::index::LayerFileMetadata; use crate::tenant::storage_layer::{Layer, ValueReconstructResult, ValueReconstructState}; use anyhow::{bail, Result}; -use pageserver_api::models::HistoricLayerInfo; +use pageserver_api::models::{HistoricLayerInfo, Key}; use std::ops::Range; use std::path::PathBuf; use std::sync::Arc; @@ -144,8 +143,8 @@ impl PersistentLayer for RemoteLayer { if self.is_delta { HistoricLayerInfo::Delta { layer_file_name, - key_start: key_range.start.to_string(), - key_end: key_range.end.to_string(), + key_start: key_range.start, + key_end: key_range.end, lsn_start: lsn_range.start, lsn_end: lsn_range.end, remote: true, @@ -153,8 +152,8 @@ impl PersistentLayer for RemoteLayer { } else { HistoricLayerInfo::Image { layer_file_name, - key_start: key_range.start.to_string(), - key_end: key_range.end.to_string(), + key_start: key_range.start, + key_end: key_range.end, lsn_start: lsn_range.start, remote: true, } diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index 2e2d3e2e22..1d3520583c 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -10,7 +10,7 @@ use itertools::Itertools; use once_cell::sync::OnceCell; use pageserver_api::models::{ DownloadRemoteLayersTaskInfo, DownloadRemoteLayersTaskSpawnRequest, - DownloadRemoteLayersTaskState, LayerMapInfo, TimelineState, + DownloadRemoteLayersTaskState, Key, LayerMapInfo, TimelineState, }; use tokio::sync::{oneshot, watch, Semaphore, TryAcquireError}; use tokio_util::sync::CancellationToken; @@ -60,7 +60,7 @@ use utils::{ use crate::page_cache; use crate::repository::GcResult; -use crate::repository::{Key, Value}; +use crate::repository::Value; use crate::task_mgr::TaskKind; use crate::walredo::WalRedoManager; use crate::METADATA_FILE_NAME; diff --git a/pageserver/src/walredo.rs b/pageserver/src/walredo.rs index c943bf0a27..ccd3f45ab1 100644 --- a/pageserver/src/walredo.rs +++ b/pageserver/src/walredo.rs @@ -21,6 +21,7 @@ use byteorder::{ByteOrder, LittleEndian}; use bytes::{BufMut, Bytes, BytesMut}; use nix::poll::*; +use pageserver_api::models::Key; use serde::Serialize; use std::collections::VecDeque; use std::fs::OpenOptions; @@ -46,7 +47,6 @@ use crate::metrics::{ WAL_REDO_WAIT_TIME, }; use crate::pgdatadir_mapping::{key_to_rel_block, key_to_slru_block}; -use crate::repository::Key; use crate::task_mgr::BACKGROUND_RUNTIME; use crate::walrecord::NeonWalRecord; use crate::{config::PageServerConf, TEMP_FILE_SUFFIX}; @@ -1153,9 +1153,9 @@ fn build_get_page_msg(tag: BufferTag, buf: &mut Vec) { #[cfg(test)] mod tests { use super::{PostgresRedoManager, WalRedoManager}; - use crate::repository::Key; use crate::{config::PageServerConf, walrecord::NeonWalRecord}; use bytes::Bytes; + use pageserver_api::models::Key; use std::str::FromStr; use utils::{id::TenantId, lsn::Lsn};