Project ideas

I was trying to come up with some ideas for projects to build with Rust. The key value store is coming along, but it's sort of boring. Mostly, I don't like dealing with HTTP, which is where I'm kind of stuck (the KV store part works, including disk persistence). On the bus ride home, I started a list of ideas, and also wrote up a short template spec for thinking through and designing systems. Here's what I've got.

  1. TCP proxy

    • topics: network programming
    • example usage: tcp-proxy -f :80 -t 127.0.0.1:8080
    • -f: from
    • -t: to
    • Advanced

      • multiple backends (e.g. load balancing)
        • this will require session tracking
  2. HTTP proxy

    • topics: network programming, configuration files
    • aka a reverse proxy
    • simple:
    • Advanced
      • service proxy: hostname ⇒ backend
      • load balancing
      • SSL termination
  3. LRU/MRU cache

    • topics: data structures
    • selectable policy
    • simple version: basic structure
    • Advanced
      • play with different data structures
      • ex. balanced B-tree
      • enforce a maximum lifetime for a cache item to prevent stale entries.
    • example:
/// The CachePolicy defines the eviction scheme for the cache.
pub enum CachePolicy {
    LRU,
    MRU,
}

/// An Entry stores a value with the last access time. Access is defined
/// as either read or write.
#[derive(Debug, Hashable)]
struct Entry<T> {
    value: T,
    atime: i64,
}

/// A Cache stores a finite-size set of items, evicting items as needed.
pub struct Cache<K: Hashable, V> {
    /// values stores the values in the cache.
    values: HashMap<K, Entry<V>>,

    /// `max_size` dictates the maximum size of the cache.
    max_size: usize,

    /// `policy` controls the eviction policy.
    policy: CachePolicy,

    /// `evict_next` is used as a shortcut to keep track of the next
    /// item that should be evicted.
    evict_next: K,
}

// Note: the implementation below contains only function signatures.
impl Cache<K: Hashable, V> {
    /// `has` returns true if the key is in the cache.
    pub fn has(&self, key: K) -> bool;

    /// `get` retrieves the entry from the cache.
    pub fn get(&self, key: K) -> Option<Entry<V>>;

    /// `set` sets the item in the cache. If the maximum size of the
    /// cache has been reached, evict an item according to the policy.
    pub fn set(&mut self, key: K, value: V);

    /// `delete` removes an item in the cache.
    pub fn delete(&mut self, key: K);

    /// `capacity` returns the number of items that may be stored in
    /// the cache without evicting an item.
    pub fn capacity(&self) -> usize;

    /// `flush` removes all entries from the cache.
    pub fn flush(&self);
}

Tags: