Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/saluki-components/src/destinations/prometheus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ use saluki_io::net::{
ListenAddress,
};
use serde::Deserialize;
use stringtheory::{interning::FixedSizeInterner, MetaString};
use stringtheory::{
interning::{FixedSizeInterner, Interner as _},
MetaString,
};
use tokio::{select, sync::RwLock};
use tracing::debug;

Expand Down
5 changes: 4 additions & 1 deletion lib/saluki-context/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use saluki_common::{
};
use saluki_error::{generic_error, GenericError};
use saluki_metrics::static_metrics;
use stringtheory::{interning::GenericMapInterner, CheapMetaString, MetaString};
use stringtheory::{
interning::{GenericMapInterner, Interner as _},
CheapMetaString, MetaString,
};
use tokio::time::sleep;
use tracing::debug;

Expand Down
2 changes: 1 addition & 1 deletion lib/saluki-env/src/workload/collectors/containerd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use saluki_config::GenericConfiguration;
use saluki_error::GenericError;
use saluki_health::Health;
use saluki_metrics::static_metrics;
use stringtheory::interning::GenericMapInterner;
use stringtheory::interning::{GenericMapInterner, Interner as _};
use tokio::{select, sync::mpsc, time::sleep};
use tracing::{debug, error, warn};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use saluki_context::{
};
use saluki_error::GenericError;
use saluki_health::Health;
use stringtheory::{interning::GenericMapInterner, MetaString};
use stringtheory::{
interning::{GenericMapInterner, Interner as _},
MetaString,
};
use tokio::{select, sync::mpsc};
use tracing::{debug, trace, warn};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use saluki_context::origin::ExternalData;
use saluki_error::GenericError;
use saluki_health::Health;
use saluki_metrics::static_metrics;
use stringtheory::{interning::GenericMapInterner, MetaString};
use stringtheory::{
interning::{GenericMapInterner, Interner as _},
MetaString,
};
use tokio::{select, sync::mpsc};
use tracing::{debug, trace};

Expand Down
5 changes: 4 additions & 1 deletion lib/saluki-env/src/workload/helpers/cgroups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use std::{
use regex::Regex;
use saluki_config::GenericConfiguration;
use saluki_error::{generic_error, ErrorContext as _, GenericError};
use stringtheory::{interning::GenericMapInterner, MetaString};
use stringtheory::{
interning::{GenericMapInterner, Interner as _},
MetaString,
};
use tracing::{debug, error, trace};

use crate::features::{Feature, FeatureDetector};
Expand Down
4 changes: 4 additions & 0 deletions lib/saluki-env/src/workload/on_demand_pid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ impl OnDemandPIDResolver {
pub fn from_configuration(
config: &GenericConfiguration, feature_detector: FeatureDetector, interner: GenericMapInterner,
) -> Result<Self, GenericError> {
use stringtheory::interning::Interner as _;

let telemetry = Telemetry::new();
telemetry
.interner_capacity_bytes()
Expand Down Expand Up @@ -128,6 +130,8 @@ impl OnDemandPIDResolver {

#[cfg(target_os = "linux")]
async fn drive_telemetry(interner: GenericMapInterner, telemetry: Telemetry) {
use stringtheory::interning::Interner as _;

loop {
sleep(Duration::from_secs(1)).await;

Expand Down
24 changes: 9 additions & 15 deletions lib/stringtheory/src/interning/fixed_size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use loom::sync::{atomic::AtomicUsize, Arc, Mutex};

use super::{
helpers::{aligned, aligned_string, hash_string, layout_for_data, PackedLengthCapacity},
InternedString, InternerVtable, ReclaimedEntries, ReclaimedEntry,
InternedString, Interner, InternerVtable, ReclaimedEntries, ReclaimedEntry,
};

const HEADER_LEN: usize = std::mem::size_of::<EntryHeader>();
Expand Down Expand Up @@ -589,7 +589,7 @@ impl<const SHARD_FACTOR: usize> InternerState<SHARD_FACTOR> {
/// ┗━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛
/// ▲ ▲ ▲
/// └────────── `EntryHeader` ──────────┘ └── aligned for `EntryHeader`
/// (8 byte alignment) via trailing padding 
/// (8 byte alignment) via trailing padding
/// ```
///
/// The backing buffer is always aligned properly for `EntryHeader`, so that the first entry can be referenced
Expand Down Expand Up @@ -643,32 +643,26 @@ impl<const SHARD_FACTOR: usize> FixedSizeInterner<SHARD_FACTOR> {
state: Arc::new(InternerState::with_capacity(capacity)),
}
}
}

/// Returns `true` if the interner contains no strings.
pub fn is_empty(&self) -> bool {
impl<const SHARD_FACTOR: usize> Interner for FixedSizeInterner<SHARD_FACTOR> {
fn is_empty(&self) -> bool {
self.state.is_empty()
}

/// Returns the number of strings in the interner.
pub fn len(&self) -> usize {
fn len(&self) -> usize {
self.state.len()
}

/// Returns the total number of bytes in the interner.
pub fn len_bytes(&self) -> usize {
fn len_bytes(&self) -> usize {
self.state.len_bytes()
}

/// Returns the total number of bytes the interner can hold.
pub fn capacity_bytes(&self) -> usize {
fn capacity_bytes(&self) -> usize {
self.state.capacity_bytes()
}

/// Tries to intern the given string.
///
/// If the intern is at capacity and the given string cannot fit, `None` is returned. Otherwise, `Some` is
/// returned with a reference to the interned string.
pub fn try_intern(&self, s: &str) -> Option<InternedString> {
fn try_intern(&self, s: &str) -> Option<InternedString> {
self.state.try_intern(s)
}
}
Expand Down
24 changes: 9 additions & 15 deletions lib/stringtheory/src/interning/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use loom::sync::{atomic::AtomicUsize, Arc, Mutex};

use super::{
helpers::{aligned_string, layout_for_data, PackedLengthCapacity},
InternedString, InternerVtable, ReclaimedEntries, ReclaimedEntry,
InternedString, Interner, InternerVtable, ReclaimedEntries, ReclaimedEntry,
};

const HEADER_LEN: usize = std::mem::size_of::<EntryHeader>();
Expand Down Expand Up @@ -532,7 +532,7 @@ unsafe impl Sync for InternerState {}
/// ┗━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛
/// ▲ ▲ ▲
/// └────────── `EntryHeader` ──────────┘ └── aligned for `EntryHeader`
/// (8 byte alignment) via trailing padding
/// (8 byte alignment) via trailing padding
/// ```
///
/// The backing buffer is always aligned properly for `EntryHeader`, so that the first entry can be referenced
Expand Down Expand Up @@ -586,32 +586,26 @@ impl GenericMapInterner {
state: Arc::new(Mutex::new(InternerState::with_capacity(capacity))),
}
}
}

/// Returns `true` if the interner contains no strings.
pub fn is_empty(&self) -> bool {
impl Interner for GenericMapInterner {
fn is_empty(&self) -> bool {
self.state.lock().unwrap().entries.is_empty()
}

/// Returns the number of strings in the interner.
pub fn len(&self) -> usize {
fn len(&self) -> usize {
self.state.lock().unwrap().entries.len()
}

/// Returns the total number of bytes in the interner.
pub fn len_bytes(&self) -> usize {
fn len_bytes(&self) -> usize {
self.state.lock().unwrap().storage.len
}

/// Returns the total number of bytes the interner can hold.
pub fn capacity_bytes(&self) -> usize {
fn capacity_bytes(&self) -> usize {
self.state.lock().unwrap().storage.capacity.get()
}

/// Tries to intern the given string.
///
/// If the intern is at capacity and the given string cannot fit, `None` is returned. Otherwise, `Some` is
/// returned with a reference to the interned string.
pub fn try_intern(&self, s: &str) -> Option<InternedString> {
fn try_intern(&self, s: &str) -> Option<InternedString> {
let header = {
let mut state = self.state.lock().unwrap();
state.try_intern(s)?
Expand Down
20 changes: 20 additions & 0 deletions lib/stringtheory/src/interning/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@ mod helpers;
mod map;
pub use self::map::GenericMapInterner;

/// A string interner.
pub trait Interner {
/// Returns `true` if the interner contains no strings.
fn is_empty(&self) -> bool;

/// Returns the number of strings in the interner.
fn len(&self) -> usize;

/// Returns the total number of bytes in the interner.
fn len_bytes(&self) -> usize;

/// Returns the total number of bytes the interner can hold.
fn capacity_bytes(&self) -> usize;

/// Attempts to intern the given string.
///
/// Returns `None` if the interner is full or the string cannot fit.
fn try_intern(&self, s: &str) -> Option<InternedString>;
}

pub(crate) struct InternerVtable {
/// Name of the interner implementation that this string was interned with.
pub interner_name: &'static str,
Expand Down
1 change: 1 addition & 0 deletions lib/stringtheory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ mod tests {
use proptest::{prelude::*, proptest};

use super::{interning::GenericMapInterner, InlinedUnion, Inner, MetaString, UnionType};
use crate::interning::Interner as _;

#[test]
fn struct_sizes() {
Expand Down