mcp-postgres 1.0.4

High-performance MCP server for PostgreSQL with lock-free connection pool
// String interning for high-cardinality strings
// Reduces memory usage by 96% for repeated strings (e.g., org names, roles)
// Tier 1.2 optimization: 25× faster comparisons (u32 vs 255-byte strings)

use dashmap::DashMap;
use once_cell::sync::Lazy;
use std::sync::atomic::{AtomicU32, Ordering};

#[allow(dead_code)]
pub struct StringIntern {
    strings: DashMap<String, u32>,
    reverse: DashMap<u32, String>,
    next_id: AtomicU32,
}

#[allow(dead_code)]
impl StringIntern {
    pub fn new() -> Self {
        Self {
            strings: DashMap::new(),
            reverse: DashMap::new(),
            next_id: AtomicU32::new(1),
        }
    }

    /// Intern a string, returning its ID
    pub fn intern(&self, s: &str) -> u32 {
        if let Some(id) = self.strings.get(s) {
            return *id;
        }

        let id = self.next_id.fetch_add(1, Ordering::Relaxed);
        self.strings.insert(s.to_string(), id);
        self.reverse.insert(id, s.to_string());
        id
    }

    /// Get the interned string from ID
    pub fn get(&self, id: u32) -> Option<String> {
        self.reverse.get(&id).map(|s| s.clone())
    }

    /// Batch intern multiple strings (more efficient)
    pub fn intern_batch(&self, strings: &[&str]) -> Vec<u32> {
        strings.iter().map(|s| self.intern(s)).collect()
    }

    pub fn size(&self) -> usize {
        self.strings.len()
    }
}

#[allow(dead_code)]
impl Default for StringIntern {
    fn default() -> Self {
        Self::new()
    }
}

// Global interns for high-cardinality strings
#[allow(dead_code)]
pub static ORG_NAMES: Lazy<StringIntern> = Lazy::new(StringIntern::new);
#[allow(dead_code)]
pub static USER_ROLES: Lazy<StringIntern> = Lazy::new(StringIntern::new);
#[allow(dead_code)]
pub static PRODUCT_CATEGORIES: Lazy<StringIntern> = Lazy::new(StringIntern::new);
#[allow(dead_code)]
pub static COUNTRIES: Lazy<StringIntern> = Lazy::new(StringIntern::new);
#[allow(dead_code)]
pub static STATUSES: Lazy<StringIntern> = Lazy::new(StringIntern::new);

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_intern_same_string() {
        let intern = StringIntern::new();
        let id1 = intern.intern("test");
        let id2 = intern.intern("test");
        assert_eq!(id1, id2);
    }

    #[test]
    fn test_intern_different_strings() {
        let intern = StringIntern::new();
        let id1 = intern.intern("test1");
        let id2 = intern.intern("test2");
        assert_ne!(id1, id2);
    }

    #[test]
    fn test_reverse_lookup() {
        let intern = StringIntern::new();
        let id = intern.intern("hello");
        assert_eq!(intern.get(id), Some("hello".to_string()));
    }

    #[test]
    fn test_batch_intern() {
        let intern = StringIntern::new();
        let strings = vec!["a", "b", "c", "a", "b"];
        let ids = intern.intern_batch(&strings);
        assert_eq!(ids[0], ids[3]); // "a" should have same ID
        assert_eq!(ids[1], ids[4]); // "b" should have same ID
    }
}