Skip to content

Sudharshan45/Cache-System

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cache System - Low Level Design

A comprehensive, thread-safe cache system implementation in Java with configurable eviction policies, TTL support, and performance monitoring.

🏗️ Architecture Overview

This cache system follows modern software design principles and patterns:

  • Strategy Pattern: Pluggable eviction policies (FIFO, LRU, LFU)
  • Factory Method Pattern: Cache creation with different configurations
  • Singleton Pattern: Statistics tracking per cache instance
  • Template Method Pattern: Common cache operations structure
  • Observer Pattern: Policy notifications for cache events

🎯 Features

Core Functionality

  • Thread-Safe Operations: Concurrent read/write support using ReadWriteLock
  • Configurable Capacity: Set maximum cache size
  • Multiple Eviction Policies: FIFO, LRU, LFU with pluggable architecture
  • TTL Support: Time-based expiration for cache entries
  • Performance Monitoring: Hit/miss ratios, eviction counts, and detailed statistics
  • Automatic Maintenance: Background cleanup of expired entries

Eviction Policies

FIFO (First In, First Out)

  • Evicts the oldest entry based on insertion time
  • Suitable for scenarios where temporal locality is important

LRU (Least Recently Used)

  • Evicts the least recently accessed entry
  • Ideal for workloads with temporal access patterns

LFU (Least Frequently Used)

  • Evicts the least frequently accessed entry
  • Best for workloads where popularity matters more than recency

🚀 Quick Start

Prerequisites

  • Java 11 or higher
  • Maven 3.6 or higher

Building the Project

# Clone and navigate to the project
cd Cache_System

# Compile the project
mvn clean compile

# Run the application
mvn exec:java

# Run with test mode
mvn exec:java -Dexec.args="test"

Basic Usage

import com.cache.system.core.Cache;
import com.cache.system.factory.CacheFactory;
import com.cache.system.factory.CacheFactory.EvictionPolicyType;

// Create a cache with LRU eviction policy
Cache<String, String> cache = CacheFactory.createCache(100, EvictionPolicyType.LRU);

// Basic operations
cache.put("user:123", "Alice");
Optional<String> user = cache.get("user:123");
cache.remove("user:123");

// TTL operations
cache.put("session:abc", "active", 5000); // 5 second TTL

// Statistics
CacheStats stats = cache.getStats();
System.out.println("Hit rate: " + stats.getHitRate());

📁 Project Structure

src/main/java/com/cache/system/
├── core/
│   ├── Cache.java              # Cache interface
│   └── CacheImpl.java          # Main cache implementation
├── factory/
│   └── CacheFactory.java       # Factory for creating cache instances
├── model/
│   ├── CacheEntry.java         # Cache entry with metadata
│   └── CacheStats.java         # Performance statistics
├── policy/
│   ├── EvictionPolicy.java     # Eviction policy interface
│   ├── FIFOEvictionPolicy.java # FIFO implementation
│   ├── LRUEvictionPolicy.java  # LRU implementation
│   └── LFUEvictionPolicy.java  # LFU implementation
├── test/
│   └── CacheTestSuite.java     # Comprehensive test suite
└── Main.java                   # Demo application and CLI

🧪 Testing

The project includes a comprehensive test suite that covers:

  • ✅ Basic CRUD operations
  • ✅ Eviction policy correctness
  • ✅ TTL functionality
  • ✅ Thread safety under concurrent access
  • ✅ Performance and statistics tracking

Running Tests

# Run automated test suite
mvn exec:java -Dexec.args="test"

# Run interactive demo
mvn exec:java

Test Coverage

Test Category Tests Coverage
Basic Operations 6 Put, Get, Remove, Contains, Size, Clear
Eviction Policies 3 FIFO, LRU, LFU behavior verification
TTL Functionality 2 Expiration and persistence
Thread Safety 1 Concurrent operations
Performance 3 Statistics, bulk operations, capacity

🎮 Interactive Demo

The application provides an interactive CLI for testing:

cache> put user:1 Alice
✅ Put 'user:1' -> 'Alice'

cache> get user:1
✅ 'user:1' -> 'Alice'

cache> put session:abc active 5000
✅ Put 'session:abc' -> 'active' (TTL: 5000ms)

cache> stats
📊 CacheStats{hits=1, misses=0, evictions=0, puts=2, hitRate=100.00%}

Available Commands

Command Description Example
put <key> <value> [ttl] Add/update entry put user:1 Alice 5000
get <key> Retrieve entry get user:1
remove <key> Remove entry remove user:1
contains <key> Check existence contains user:1
size Show cache size size
clear Clear all entries clear
stats Show statistics stats
list List all entries list
exit Exit interactive mode exit

🔧 Configuration Options

Cache Creation

// Using factory with predefined policies
Cache<String, String> lruCache = CacheFactory.createCache(100, EvictionPolicyType.LRU);
Cache<String, String> fifoCache = CacheFactory.createCache(50, EvictionPolicyType.FIFO);
Cache<String, String> lfuCache = CacheFactory.createCache(200, EvictionPolicyType.LFU);

// Using custom eviction policy
EvictionPolicy<String, String> customPolicy = new MyCustomPolicy<>();
Cache<String, String> customCache = CacheFactory.createCache(100, customPolicy);

Performance Tuning

  • Capacity: Choose based on available memory and expected data size
  • Eviction Policy:
    • Use LRU for temporal locality
    • Use LFU for frequency-based access
    • Use FIFO for simple time-based eviction
  • TTL: Set appropriate expiration times for temporary data

🔒 Thread Safety

The cache implementation provides thread safety through:

  • ReadWriteLock: Allows concurrent reads while ensuring exclusive writes
  • ConcurrentHashMap: Thread-safe internal storage
  • Atomic Operations: For statistics tracking
  • Synchronized Methods: For eviction policy operations

Concurrent Performance

// Example: Concurrent access pattern
ExecutorService executor = Executors.newFixedThreadPool(10);
Cache<String, String> cache = CacheFactory.createCache(1000, EvictionPolicyType.LRU);

// Multiple threads can safely access the cache simultaneously
for (int i = 0; i < 10; i++) {
    executor.submit(() -> {
        cache.put("key" + Thread.currentThread().getId(), "value");
        cache.get("key" + Thread.currentThread().getId());
    });
}

📊 Performance Characteristics

Operation Time Complexity Thread Safety
Put O(1) average ✅ Thread-safe
Get O(1) average ✅ Thread-safe
Remove O(1) average ✅ Thread-safe
Contains O(1) average ✅ Thread-safe
Eviction O(1) - O(n) ✅ Thread-safe

Memory Usage

  • Each cache entry has minimal overhead (key, value, metadata)
  • Eviction policies maintain lightweight tracking structures
  • Automatic cleanup prevents memory leaks from expired entries

🛠️ Design Principles Applied

SOLID Principles

  1. Single Responsibility: Each class has a single, well-defined purpose
  2. Open/Closed: Easy to extend with new eviction policies
  3. Liskov Substitution: All eviction policies are interchangeable
  4. Interface Segregation: Focused interfaces for different concerns
  5. Dependency Inversion: Depends on abstractions, not concrete implementations

Design Patterns

  • Strategy: Eviction policies
  • Factory Method: Cache creation
  • Template Method: Common cache operations
  • Observer: Policy notifications

🚀 Extending the System

Adding Custom Eviction Policy

public class TimeBasedEvictionPolicy<K, V> implements EvictionPolicy<K, V> {
    private final Map<K, LocalDateTime> accessTimes = new ConcurrentHashMap<>();
    
    @Override
    public void onEntryAccess(CacheEntry<K, V> entry) {
        accessTimes.put(entry.getKey(), LocalDateTime.now());
    }
    
    @Override
    public K selectKeyToEvict() {
        return accessTimes.entrySet().stream()
            .min(Map.Entry.comparingByValue())
            .map(Map.Entry::getKey)
            .orElse(null);
    }
    
    // Implement other required methods...
}

Custom Cache Configuration

// Create cache with custom policy
EvictionPolicy<String, String> customPolicy = new TimeBasedEvictionPolicy<>();
Cache<String, String> cache = CacheFactory.createCache(100, customPolicy);

📈 Production Considerations

Monitoring

// Regular statistics monitoring
CacheStats stats = cache.getStats();
logger.info("Cache performance - Hit rate: {}%, Evictions: {}", 
    stats.getHitRate() * 100, stats.getEvictions());

Graceful Shutdown

// Ensure proper cleanup
if (cache instanceof CacheImpl) {
    ((CacheImpl<?, ?>) cache).shutdown();
}

Memory Management

  • Monitor cache size relative to available heap memory
  • Set appropriate TTL for temporary data
  • Consider implementing cache warming strategies

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add comprehensive tests
  4. Follow existing code style and patterns
  5. Submit a pull request

📝 License

This project is available under the MIT License.


Built with ❤️ using Java, Maven, and software engineering best practices.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages