# Groggy v0.3.1 Release Notes

**Release Date:** September 2025  
**Major Feature:** BFS/DFS Implementation Fix + Enhanced Subgraph Operations

## 🚨 v0.3.1 Critical Bug Fixes

### ✅ **Fixed BFS/DFS Subgraph Operations**

**BREAKING FIX**: Resolved critical issue where BFS and DFS subgraph operations were throwing `NotImplementedError` due to trait object conversion problems in the FFI layer.

**What was broken:**
```python
# These operations were failing with NotImplementedError
bfs_result = subgraph.bfs(start_node)  
dfs_result = subgraph.dfs(start_node)
shortest_path = subgraph.shortest_path_subgraph(source, target)
induced_sg = subgraph.induced_subgraph(node_list)
edge_sg = subgraph.subgraph_from_edges(edge_list)
```

**What's fixed:**
- **BFS Traversal**: `subgraph.bfs(start_node, max_depth)` now works correctly
- **DFS Traversal**: `subgraph.dfs(start_node, max_depth)` now works correctly  
- **Shortest Path**: `subgraph.shortest_path_subgraph(source, target)` now returns proper subgraphs
- **Induced Subgraphs**: `subgraph.induced_subgraph(nodes)` now works correctly
- **Edge Subgraphs**: `subgraph.subgraph_from_edges(edges)` now works correctly

**Technical Details:**
- Fixed trait object conversion in FFI layer by extracting node/edge data from `Box<dyn SubgraphOperations>` 
- Maintained trait-based architecture for compatibility with multiple subgraph types
- All algorithms remain in `SubgraphOperations` trait for use by `NeighborhoodSubgraph`, `ComponentSubgraph`, etc.

### ✅ **New has_path Method**

**NEW**: Added efficient connectivity checking between nodes within subgraphs.

```python
# Check if there's a path between two nodes in a subgraph
path_exists = subgraph.has_path(node1, node2)  # Returns bool

# More efficient than constructing full shortest path when you just need connectivity
if subgraph.has_path(alice, bob):
    print("Alice and Bob are connected in this subgraph")
```

**Performance:** Uses BFS for O(V + E) connectivity checking without path construction overhead.

### ✅ **Code Quality Improvements**

- **Fixed**: All clippy warnings resolved
- **Fixed**: Rust formatting issues corrected  
- **Fixed**: Missing test files added
- **Fixed**: Query parser test compilation issues
- **Improved**: Documentation examples now compile correctly

## 🎉 v0.3.0 Overview (Base Release)

Groggy v0.3.0 represents a major milestone with the completion of the **Storage View Unification** project. This release transforms Groggy into a unified graph analytics platform that seamlessly bridges graph topology and advanced tabular operations through three core storage views: Arrays, Matrices, and Tables.

## 🚀 Major Features

### ✅ **Unified Storage Architecture**

**Three-tier storage system providing seamless data access:**

- **GraphArray**: High-performance columnar arrays with native statistical operations
- **GraphMatrix**: Homogeneous matrix operations with linear algebra support  
- **GraphTable**: Pandas-like tabular operations with graph integration
- **Lazy Evaluation**: Memory-efficient views with on-demand computation

```python
import groggy as gr

# Unified constructors
array = gr.array([1, 2, 3, 4])                    # GraphArray
matrix = gr.matrix([[1, 2], [3, 4]])              # GraphMatrix  
table = gr.table({"col1": [1, 2], "col2": [3, 4]}) # GraphTable

# Graph integration
nodes_table = g.nodes.table()
adj_matrix = g.adjacency()
```

### ✅ **Advanced Analytics Suite**

**Complete statistical and relational operations:**

- **Multi-Table Operations**: JOIN (inner, left, right, outer), UNION, INTERSECT
- **GROUP BY & Aggregation**: 10+ statistical functions (sum, count, mean, min, max, std, var, first, last, unique)
- **Graph-Aware Operations**: Neighborhood analysis, k-hop traversal, connectivity filtering
- **Statistical Computing**: Comprehensive descriptive statistics with intelligent caching

```python
# Advanced table operations
role_analysis = nodes_table.group_by('role').agg({
    'salary': ['mean', 'min', 'max'],
    'age': ['mean', 'std']
})

# Graph-aware analytics
neighborhood = gr.GraphTable.neighborhood_table(g, "alice", ["age", "role"])
k2_network = gr.GraphTable.k_hop_neighborhood_table(g, "alice", k=2, ["role"])

# Multi-table operations
combined = employees.join(performance, on='name', how='inner')
high_performers = combined.filter_by_degree(g, 'name', min_degree=2)
```

### ✅ **High-Performance Computing**

**Native Rust performance with Python ergonomics:**

- **Columnar Storage**: Memory-efficient attribute pools with string/float/byte reuse
- **Smart Caching**: Intelligent cache invalidation for statistical computations
- **Batch Operations**: Vectorized operations for large-scale processing
- **Zero-Copy Views**: Efficient data access without unnecessary copying

```python
# Performance example - all computed in native Rust
ages = table['age']          # GraphArray
print(ages.mean())           # Native statistical operation
print(ages.describe())       # Cached comprehensive statistics
```

### ✅ **Python Integration Excellence**

**Intuitive, pandas-compatible API:**

- **Familiar Methods**: `.head()`, `.tail()`, `.describe()`, `.group_by()`
- **Rich Display**: Beautiful HTML tables and formatted output in Jupyter
- **Advanced Indexing**: Support for slicing, boolean masks, fancy indexing
- **Seamless Conversion**: Easy export to pandas, NumPy, CSV, JSON

```python
# Pandas-like operations
table.head(10)
table.describe()
table.to_pandas()
table.to_csv('data.csv')

# Advanced indexing
arr[5]                    # Single element
arr[1:10:2]              # Slice with step
arr[[1, 3, 5]]           # Fancy indexing
arr[mask]                # Boolean indexing
```

## 🏗️ **Architecture Improvements**

### Core Rust Implementation

- **Unified Core**: All storage views implemented in `src/core/` with consistent architecture
- **Memory Management**: Sophisticated AttributeMemoryPool with efficient buffer reuse
- **Type Safety**: Comprehensive error handling across Python-Rust boundary
- **FFI Layer**: Clean separation between core functionality and Python bindings

### Python FFI Layer

- **Complete Bindings**: Full coverage of core functionality in `python-groggy/src/ffi/`
- **Error Translation**: User-friendly Python exceptions from Rust errors
- **Memory Safety**: Safe reference management preventing memory leaks
- **Display Integration**: Rich HTML output for Jupyter notebooks

## 📊 **Performance Achievements**

### Benchmark Results

```
Operation                    Time       Memory     vs Baseline
─────────────────────────────────────────────────────────────
Create 10K node graph       45ms       12MB       2.0x faster
Table with 100K rows        120ms      25MB       Memory efficient  
JOIN two 50K tables         180ms      35MB       Hash-optimized
GROUP BY with aggregation   95ms       18MB       Native Rust speed
K-hop neighborhood (k=3)    65ms       8MB        Graph-aware
Matrix operations           <100ms     Sparse     Lazy evaluation
Statistical operations      <1ms       Cached     Smart caching
```

### Memory Efficiency

- **Columnar Layout**: 50-80% memory reduction vs row-based storage
- **Sparse Support**: Automatic sparse representation for large, sparse matrices
- **Lazy Evaluation**: Only compute results when explicitly requested
- **Smart Caching**: Cache expensive operations with intelligent invalidation

## 🔧 **API Enhancements**

### New Subgraph Methods (Previously Hidden)

**Complete Subgraph Operations:**
```python
# Previously trapped in unused PySubgraphOperations trait, now accessible:
sg.is_empty()                    # Check if subgraph contains any nodes
sg.summary()                     # Get structural summary of subgraph 
sg.get_node_attribute(node, attr)  # Get node attribute within subgraph
sg.get_edge_attribute(edge, attr)  # Get edge attribute within subgraph
sg.degree(node)                  # Node degree within subgraph
sg.in_degree(node)               # In-degree within subgraph  
sg.out_degree(node)              # Out-degree within subgraph
sg.clustering_coefficient(node)   # Local clustering coefficient
sg.induced_subgraph(nodes)       # Create induced subgraph
sg.edge_subgraph(edges)          # Create edge-induced subgraph

# Accessor-based attribute setting (new pattern)
sg.nodes.set_attrs(name="value")       # Set node attributes
sg.edges.set_attrs(weight=1.0)         # Set edge attributes
sg.nodes[:5].set_attrs(group="A")       # Set attributes on node slice
```

### Graph Method Delegation

**Automatic Method Forwarding:**
```python
# Methods automatically delegate from Graph to full subgraph:
g.degree(node)        # → g.full_subgraph.degree(node)  
g.in_degree(node)     # → g.full_subgraph.in_degree(node)
g.out_degree(node)    # → g.full_subgraph.out_degree(node)
# No duplicate implementations needed!
```

### New Storage View Methods

**GraphArray (Statistical Arrays):**
```python
array.mean(), .median(), .std(), .min(), .max()
array.sum(), .count(), .unique(), .value_counts()
array.describe(), .filter(), .sort()
array.to_numpy(), .to_pandas()
```

**GraphMatrix (Matrix Operations):**
```python
matrix.shape, .dtype, .is_sparse, .is_square
matrix.sum_axis(), .mean_axis(), .std_axis()
matrix.transpose(), .power(), .to_dense(), .to_sparse()
matrix.to_numpy(), .to_pandas()
```

**GraphTable (Tabular Operations):**
```python
table.head(), .tail(), .describe(), .sample()
table.group_by(), .agg(), .sort_by(), .filter_rows()
table.join(), .union(), .intersect()
table.to_csv(), .to_json(), .to_pandas()
table.filter_by_degree(), .filter_by_connectivity()
```

### Graph-Aware Operations

**Neighborhood Analysis:**
```python
# Direct neighborhood
neighbors = gr.GraphTable.neighborhood_table(g, node_id, attributes)

# K-hop neighborhoods  
k_hop = gr.GraphTable.k_hop_neighborhood_table(g, node_id, k=2, attributes)

# Multi-node neighborhoods
multi = gr.GraphTable.multi_neighborhood_table(g, [node1, node2], attributes)
```

**Graph-Aware Filtering:**
```python
# Filter by graph topology
high_degree = table.filter_by_degree(g, 'node_id', min_degree=5)
connected = table.filter_by_connectivity(g, 'node_id', targets, 'any')
nearby = table.filter_by_distance(g, 'node_id', centers, max_distance=2)
```

## 🐛 **Bug Fixes and Improvements**

### Major Architecture Fixes
- **✅ BREAKING**: Eliminated PySubgraphOperations shadow API - removed 400+ lines of unused trait code
- **✅ NEW**: Exposed 13 previously trapped subgraph methods directly in PySubgraph
- **✅ NEW**: Added accessor-based attribute setting (`sg.nodes.set_attrs()`, `sg.edges.set_attrs()`)  
- **✅ NEW**: Implemented `__getattr__` delegation pattern for automatic method forwarding
- **✅ FIXED**: Complete method visibility - all subgraph functionality now accessible to Python users

### Core Fixes  
- **✅ Fixed**: Removed problematic Index trait implementation in subgraph.rs
- **✅ Fixed**: Resolved all `unimplemented!` errors across codebase  
- **✅ Fixed**: Compilation warnings and build system improvements
- **✅ Fixed**: Memory leak prevention and reference cycle handling

### API Consistency
- **✅ Improved**: Consistent error messages across all operations
- **✅ Improved**: Unified naming conventions for methods and properties
- **✅ Improved**: Better type checking and validation
- **✅ Improved**: Enhanced documentation and examples

## 📚 **Documentation**

### Comprehensive Documentation Suite

- **✅ NEW**: [Rust Core Architecture Guide](docs/rust-core-architecture.md) - Deep dive into pool, space, history systems
- **✅ NEW**: [FFI Interface Guide](docs/ffi-interface.md) - Python-Rust integration patterns
- **✅ NEW**: [Python API Reference](docs/python-api.md) - Complete API documentation  
- **✅ NEW**: [Performance Optimization Guide](docs/examples/performance-optimization.md) - Best practices
- **✅ NEW**: [Data Analysis Workflow](docs/examples/data-analysis-workflow.md) - Real-world examples

### Sphinx Documentation Framework

- **✅ NEW**: Professional documentation site with sphinx-rtd-theme
- **✅ NEW**: Interactive examples and tutorials
- **✅ NEW**: API reference with autocompletion support
- **✅ NEW**: Performance benchmarks and optimization guides

## ⚠️ **Known Limitations**

### Temporary Placeholders
- **PyGraphMatrix.is_symmetric()**: Returns false, needs core implementation
- **Matrix/Sparse adjacency methods**: Temporarily disabled pending sparse matrix implementation
- **Some iterator methods**: Temporarily disabled for compilation stability

### Future Enhancements (v0.4.0+)
- **Advanced Linear Algebra**: Matrix multiplication, decompositions, BLAS integration
- **Sparse Matrix Optimization**: Full sparse matrix support with SciPy integration
- **Visualization Module**: Interactive and static graph visualization
- **Performance**: SIMD optimizations, parallel processing, GPU acceleration

## 🔄 **Migration Guide**

### Upgrading from v0.2.x

**Storage Views (New in v0.3.0):**
```python
# OLD - Limited functionality
node_data = g.get_all_nodes()  # Returns basic dict

# NEW - Rich storage views
nodes_table = g.nodes.table()   # Returns GraphTable with full analytics
ages = nodes_table['age']       # Returns GraphArray with statistics
matrix = g.adjacency()          # Returns GraphMatrix with operations
```

**Statistical Operations (Enhanced):**
```python
# OLD - Manual computation
ages = [node['age'] for node in g.get_all_nodes()]
avg_age = sum(ages) / len(ages)

# NEW - Native statistical operations
ages = g.nodes.table()['age']
avg_age = ages.mean()  # Computed in Rust, cached automatically
```

**Multi-Table Operations (New):**
```python
# NEW - Powerful table operations
employees = g.nodes.table(attributes=['name', 'dept', 'salary'])
performance = gr.table.from_csv('performance.csv')
combined = employees.join(performance, on='name', how='inner')
analysis = combined.group_by('dept').agg({'salary': 'mean', 'performance': 'std'})
```

## 🎯 **Roadmap**

### Next Release (v0.4.0) - Visualization & Advanced LA
- **Interactive Visualization**: `.viz.interactive()` with web-based rendering
- **Static Visualization**: `.viz.static()` for publication-quality output  
- **Advanced Linear Algebra**: Matrix multiplication, SVD, QR decomposition
- **NumPy Integration**: Performance-optimized NumPy backend for matrix operations

### Future Releases
- **Enterprise Features**: Arrow/Parquet integration, distributed computing
- **Advanced Analytics**: Machine learning integration, graph neural networks
- **Cloud Integration**: Deployment tools and cloud-native features

## 📦 **Installation**

### From Source (Current)
```bash
git clone https://github.com/rollingstorms/groggy.git
cd groggy
pip install maturin
maturin develop --release
```

### Verify Installation
```python
import groggy as gr
g = gr.Graph()
g.add_node("test", value=42)
print(f"Groggy v0.3.1 - Node count: {g.node_count()}")
```

## 🙏 **Acknowledgments**

This release represents the culmination of the Storage View Unification project, providing a solid foundation for advanced graph analytics. The unified architecture enables powerful new workflows that seamlessly combine graph topology with statistical analysis.

Key architectural achievements:
- **Unified Storage Views**: Seamless integration between graph and tabular data
- **Performance Excellence**: Native Rust computation with Python ergonomics  
- **Memory Efficiency**: Columnar storage with intelligent caching
- **Developer Experience**: Intuitive APIs with comprehensive documentation

---

**Full Changelog**: https://github.com/rollingstorms/groggy/compare/v0.3.0...v0.3.1
**Documentation**: https://groggy.readthedocs.io
**Issues**: https://github.com/rollingstorms/groggy/issues