# Code Understanding Cache

Intelligent code analysis caching system for accelerating repeated operations.

## Overview

Code Understanding Cache automatically caches code file analysis results, significantly speeding up repeated access to the same information. The system integrates with file operations and search extensions, providing transparent caching without modifying existing code.

## Key Features

- **Automatic caching**: Transparent caching of code analysis results
- **Smart invalidation**: Automatic cache update when files change
- **Cache warming**: Proactive cache filling for frequently used files
- **Search integration**: Automatic warming from glob/grep results
- **Statistics**: Detailed cache usage metrics (hits, misses, hit rate)
- **Memory management**: LRU eviction and cache size limits

## Quick Start

### Basic Usage

```python
from neoCoder.sdk.code_cache.cache import CodeUnderstandingCache
from neoCoder.sdk.code_cache.config import CacheConfig

# Create cache
config = CacheConfig(enabled=True)
cache = CodeUnderstandingCache(config)

# Analyze file (first time - cache miss)
analysis = cache.analyze_file("src/main.py")
print(f"Functions: {len(analysis.functions)}")
print(f"Classes: {len(analysis.classes)}")

# Repeat analysis (cache hit - faster)
analysis = cache.analyze_file("src/main.py")

# Statistics
stats = cache.get_stats()
print(f"Hit rate: {stats['hit_rate']:.1%}")
```

### Using Extension

```python
from neoCoder.sdk.code_cache.extension import CodeCacheExtension
from neoCoder.sdk.code_cache.config import CacheConfig

# Create extension
config = CacheConfig(enabled=True)
extension = CodeCacheExtension(config)

# Extension automatically:
# - Warms cache from search results
# - Invalidates cache when files change
# - Provides cache management tools
```

## Tools

### analyze_code_file

Analyzes a code file and returns detailed structure information.

```python
action = Action(
    type="tool_use",
    name="analyze_code_file",
    input={"file_path": "src/utils.py"},
)
result = extension.execute(action, context)
```

**Output:**
```
File: src/utils.py
Language: python
Lines of code: 45
Functions: 3
Classes: 1
Imports: 2

Summary:
Utility functions for data processing...

Functions:
  - load_data (complexity: 2)
  - save_data (complexity: 3)
  - process_data (complexity: 5)

Classes:
  - DataProcessor (2 methods)
```

### warm_cache_directory

Warms cache for all files in a directory.

```python
action = Action(
    type="tool_use",
    name="warm_cache_directory",
    input={"directory": "src", "recursive": True},
)
result = extension.execute(action, context)
```

**Output:**
```
Cache warming completed for: src
  Files warmed: 15
  Files skipped: 3
```

### warm_cache_related

Warms cache for files related to a given file (imports).

```python
action = Action(
    type="tool_use",
    name="warm_cache_related",
    input={"file_path": "src/main.py"},
)
result = extension.execute(action, context)
```

### get_cache_stats

Gets cache usage statistics.

```python
action = Action(
    type="tool_use",
    name="get_cache_stats",
    input={},
)
result = extension.execute(action, context)
```

**Output:**
```
Code Cache Statistics:
  Hits: 45
  Misses: 15
  Total requests: 60
  Hit rate: 75.0%
  Cache size: 15 entries
```

### clear_cache

Clears the code cache.

```python
action = Action(
    type="tool_use",
    name="clear_cache",
    input={},
)
result = extension.execute(action, context)
```

## Configuration

```python
from neoCoder.sdk.code_cache.config import CacheConfig

config = CacheConfig(
    # Basic settings
    enabled=True,                    # Enable caching
    max_entries=1000,                # Maximum cache entries
    ttl_seconds=3600,                # Entry time-to-live (1 hour)
    
    # Storage
    storage_path=None,               # Path for disk cache (None = in-memory)
    use_disk_cache=False,            # Use disk cache
    
    # Invalidation
    check_mtime=True,                # Check modification time
    check_content_hash=True,         # Check content hash
    
    # Analysis
    parse_ast=True,                  # Parse AST
    calculate_complexity=True,       # Calculate complexity
    extract_docstrings=True,         # Extract docstrings
    
    # Performance
    max_file_size_mb=10,             # Maximum file size
    async_analysis=False,            # Async analysis
)
```

## Architecture

```
CodeCacheExtension
├── CodeUnderstandingCache
│   ├── CacheStore (storage)
│   ├── CacheInvalidator (invalidation)
│   ├── CodeParser (parsing)
│   └── CodeAnalyzer (analysis)
├── on_input_messages (warming)
├── on_output_messages (invalidation)
└── Tools
```

## Supported Languages

- Python (.py)
- JavaScript (.js)
- TypeScript (.ts, .tsx)
- Java (.java)
- C/C++ (.c, .cpp, .h, .hpp)
- Go (.go)
- Rust (.rs)
- Ruby (.rb)
- PHP (.php)
- C# (.cs)
- Swift (.swift)
- Kotlin (.kt)
- Scala (.scala)
- R (.r)

## Performance

### Benchmarks

- **Speedup**: 2-10x acceleration on repeated access
- **Throughput**: >10 files/sec on first analysis
- **Hit rate**: 50-90% depending on access pattern
- **Cold start overhead**: <20% on first analysis
- **Invalidation**: <1ms per file

### Memory Usage

- **Per entry**: ~5-10KB per file
- **LRU eviction**: Automatic eviction of old entries
- **Memory limits**: Configurable entry limits

## Integration

### With FileSearchExtension

Cache is automatically warmed from search results:

```python
# FileSearchExtension finds files
search_results = {
    "artifacts": {
        "glob_matches": ["src/main.py", "src/utils.py"],
    },
}

# CodeCacheExtension automatically warms cache
extension.on_input_messages([search_results], context)
```

### With FileEditExtension

Cache is automatically invalidated when files change:

```python
# FileEditExtension modifies file
edit_result = {
    "artifacts": {
        "last_written_file": "src/utils.py",
    },
}

# CodeCacheExtension automatically invalidates cache
extension.on_output_messages([edit_result], context)
```

## Usage Examples

### Project Analysis

```python
# Warm cache for entire project
extension.warm_cache_for_directory("src", recursive=True)

# Analyze files (fast thanks to cache)
for file in ["src/main.py", "src/utils.py", "src/helpers.py"]:
    analysis = cache.analyze_file(file)
    print(f"{file}: {len(analysis.functions)} functions")
```

### Developer Workflow

```python
# 1. Search files
search_message = {"artifacts": {"glob_matches": ["src/*.py"]}}
extension.on_input_messages([search_message], context)

# 2. Analyze (cache hit)
analysis = cache.analyze_file("src/main.py")

# 3. Modify
modify_message = {"artifacts": {"last_written_file": "src/main.py"}}
extension.on_output_messages([modify_message], context)

# 4. Re-analyze (cache miss, fresh data)
analysis = cache.analyze_file("src/main.py")
```

## Testing

```bash
# Unit tests
pytest tests/unit/test_cache*.py -v

# Integration tests
pytest tests/integration/test_code_cache*.py -v

# E2E tests
pytest tests/e2e/test_code_cache_e2e.py -v

# Performance benchmarks
pytest tests/performance/test_code_cache_performance.py -v

# Memory tests
pytest tests/performance/test_code_cache_memory.py -v

# All Code Cache tests
pytest tests/ -k "code_cache" -v
```

## Metrics

### Cache Statistics

```python
stats = cache.get_stats()
# {
#     'hits': 45,
#     'misses': 15,
#     'total_requests': 60,
#     'hit_rate': 0.75,
#     'cache_size': 15
# }
```

### File Analysis

```python
analysis = cache.analyze_file("src/main.py")
# CachedFileAnalysis(
#     file_path='src/main.py',
#     metadata=FileMetadata(language='python', ...),
#     functions=[...],
#     classes=[...],
#     imports=[...],
#     summary='...',
#     loc=45,
#     cached_at=datetime(...),
#     access_count=3
# )
```

## Best Practices

1. **Warm cache proactively**: Use `warm_cache_directory` for frequently used directories
2. **Monitor hit rate**: Aim for >70% for optimal performance
3. **Configure cache size**: Set `max_entries` based on project size
4. **Use TTL**: Configure `ttl_seconds` for automatic invalidation of old entries
5. **Integrate with workflow**: Let automatic warming and invalidation work

## Troubleshooting

### Low hit rate

- Check that cache is enabled (`enabled=True`)
- Increase `max_entries` if there are many files
- Check file access pattern

### Stale data

- Ensure `check_mtime=True`
- Check that invalidation works
- Decrease `ttl_seconds`

### High memory usage

- Decrease `max_entries`
- Enable disk cache (`use_disk_cache=True`)
- Clear cache periodically

## Roadmap

- [ ] Disk cache support (persistent storage)
- [ ] Async file analysis
- [ ] Incremental analysis (only changed parts)
- [ ] Support for more programming languages
- [ ] Distributed cache for teams

## License

MIT License - see LICENSE file for details.
