cleanup: remove dead code, stale shipped scaffolding, internal docs
Dead code with zero callers (deprecation notes promised removal): - RelationCSR index: always-off option (useRelationCsrIndex), never enabled in production, wired through RelationManager/RelationUpdates/ RelationLookup. Removed the module and all wiring. - getAggregatedBlurredValue (RelationManager) and aggregateBlurredValues (ValueManager): @deprecated shims, zero callers. - QualitativeRelationalComparatorRule._aggregateBlurredValues: @deprecated shim, zero callers. Kept compareRelationValues: non-deprecated public API, coherent and clock-threaded, just currently callerless. Stale scaffolding shipping in the published artifact (files: src/): - src/ast/tests/* and src/ast/examples/*: orphaned duplicates of tests/ast/, zero references anywhere, 11 files in the tarball. Removed; the live copies live in tests/ast/. Internal docs moved out of the shipped surface (1266 lines) to docs/internal/: VALUE_OPTIMIZATION_SUMMARY, rules API_SPECIFICATION, ast README, qualitative README — repo-kept, not packaged. Tarball .md count: 11 -> 1. Rigor 251/251, full suite 853/791/0.
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
# Value Handling Optimization Summary
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the comprehensive optimization of value handling in the RuleEvaluator system, which eliminates wasteful recalculations and dramatically improves performance for complex rule evaluations.
|
||||
|
||||
## Problems Identified
|
||||
|
||||
### 1. **Redundant Value Fetching**
|
||||
- **Issue**: Multiple rules in the same evaluation tree were independently fetching the same values from relations
|
||||
- **Example**: A union rule with 3 child RelationalComparatorRules would fetch `user.balance` 3 times
|
||||
- **Impact**: O(n) redundant database/relation queries per evaluation
|
||||
|
||||
### 2. **Missing Value Propagation**
|
||||
- **Issue**: LogicalOperators (union/intersection) weren't combining `collectedValues` from child rules
|
||||
- **Impact**: Lost value information that could be reused by parent rules
|
||||
|
||||
### 3. **Wasteful Inference Triggering**
|
||||
- **Issue**: Inference engine was called even when sufficient values existed but weren't being considered
|
||||
- **Impact**: Expensive similarity calculations when values were already available
|
||||
|
||||
### 4. **No Context Sharing**
|
||||
- **Issue**: Each rule evaluation was isolated with no mechanism to share computed values
|
||||
- **Impact**: Repeated work across the evaluation tree
|
||||
|
||||
## Solution: ValueContext System
|
||||
|
||||
### Core Components
|
||||
|
||||
#### 1. **ValueContext Class** (`ValueContext.js`)
|
||||
```javascript
|
||||
export class ValueContext {
|
||||
// Centralized value cache and aggregation
|
||||
// - Value cache: entity:relation -> raw values
|
||||
// - Aggregated cache: entity:relation:method -> aggregated result
|
||||
// - Performance tracking: hits/misses/fetch counts
|
||||
}
|
||||
```
|
||||
|
||||
**Key Features:**
|
||||
- **Caching**: Eliminate redundant fetches with `entity:relation` keyed cache
|
||||
- **Aggregation**: Pre-compute and cache aggregated values (sum, max, min, etc.)
|
||||
- **Smart Inference**: Check value sufficiency before triggering expensive inference
|
||||
- **Performance Tracking**: Monitor cache hit rates and fetch reduction
|
||||
|
||||
#### 2. **Enhanced RuleEvaluator** (`RuleEvaluator.js`)
|
||||
```javascript
|
||||
evaluateRule(userId, userKey, objectId, objectKey, rule, visited, currentRelation, options = {}) {
|
||||
const { valueContext = null } = options;
|
||||
const finalValueContext = valueContext || new ValueContext(this.arbiter);
|
||||
|
||||
// Pass valueContext to all child rule evaluations
|
||||
// Add collected values to context
|
||||
// Use context to make smarter inference decisions
|
||||
}
|
||||
```
|
||||
|
||||
**Key Improvements:**
|
||||
- **Context Propagation**: Pass ValueContext through entire evaluation tree
|
||||
- **Value Collection**: Automatically add `collectedValues` to context
|
||||
- **Smart Inference**: Check `hasSufficientValues()` before expensive inference
|
||||
- **Batch Optimization**: Shared ValueContext across batch evaluations
|
||||
|
||||
#### 3. **Optimized LogicalOperators** (`LogicalOperators_v2.js`)
|
||||
```javascript
|
||||
evaluateUnion(userId, userKey, objectId, objectKey, rule, visited, currentRelation, options = {}) {
|
||||
const allCollectedValues = []; // Track from all child rules
|
||||
|
||||
for (const child of childRules) {
|
||||
const res = this.ruleEvaluator.evaluateRule(/* ... */, options);
|
||||
|
||||
// Merge collected values from child
|
||||
if (res.collectedValues) {
|
||||
allCollectedValues.push(...res.collectedValues);
|
||||
if (valueContext) {
|
||||
valueContext.addCollectedValues(res.collectedValues, child.type, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { /* ... */, collectedValues: allCollectedValues };
|
||||
}
|
||||
```
|
||||
|
||||
**Key Improvements:**
|
||||
- **Value Merging**: Combine `collectedValues` from all child rules
|
||||
- **Context Integration**: Add child values to shared ValueContext
|
||||
- **Preserved Information**: Ensure no value information is lost in logical operations
|
||||
|
||||
#### 4. **Optimized RelationalComparatorRule** (`RelationalComparatorRule_v2.js`)
|
||||
```javascript
|
||||
_evaluateOperand(/* ... */, options, side) {
|
||||
const { valueContext = null } = options;
|
||||
|
||||
// 1. Check if rule already provided values (collectedValues)
|
||||
if (ruleResult.collectedValues?.length > 0) {
|
||||
return this._useCollectedValues(ruleResult.collectedValues);
|
||||
}
|
||||
|
||||
// 2. Check ValueContext cache before extraction
|
||||
if (valueContext?.hasValues(entityId, relationName)) {
|
||||
return valueContext.getAggregatedValue(entityId, relationName, aggregator);
|
||||
}
|
||||
|
||||
// 3. Fallback to original extraction (but cache results)
|
||||
return this._extractValuesWithContext(/* ... */, valueContext);
|
||||
}
|
||||
```
|
||||
|
||||
**Key Improvements:**
|
||||
- **Cached Value Reuse**: Check ValueContext before fetching from relations
|
||||
- **Collected Value Utilization**: Prefer values from child rule `collectedValues`
|
||||
- **Fallback Safety**: Maintain backward compatibility with original extraction logic
|
||||
|
||||
## Performance Benefits
|
||||
|
||||
### Quantitative Improvements
|
||||
|
||||
#### Value Fetch Reduction
|
||||
- **Before**: O(n × m) fetches where n = rule count, m = unique values per rule
|
||||
- **After**: O(k) fetches where k = unique entity:relation combinations
|
||||
- **Typical Reduction**: 60-90% fewer database/relation queries
|
||||
|
||||
#### Cache Effectiveness
|
||||
- **Hit Rate**: 70-95% in complex rule evaluations
|
||||
- **Memory Usage**: Minimal overhead (values cached only for evaluation duration)
|
||||
- **Invalidation**: Automatic cleanup after evaluation completion
|
||||
|
||||
#### Inference Optimization
|
||||
- **Before**: Inference triggered on every zero-result rule
|
||||
- **After**: Inference only when `hasSufficientValues()` returns false
|
||||
- **Typical Reduction**: 40-70% fewer expensive inference operations
|
||||
|
||||
### Example Performance Case
|
||||
|
||||
**Scenario**: User purchasing premium feature
|
||||
```
|
||||
Rule Structure:
|
||||
└── UNION
|
||||
├── RELATIONAL_COMPARATOR (user.balance >= feature.price)
|
||||
└── INTERSECTION
|
||||
├── CHAIN (user -> subscriptions)
|
||||
└── UNION
|
||||
├── RELATIONAL_COMPARATOR (user.credit >= feature.price)
|
||||
└── RELATIONAL_COMPARATOR (user.balance >= feature.price)
|
||||
```
|
||||
|
||||
**Old System Value Fetches:**
|
||||
- `user.balance`: 2 times (redundant!)
|
||||
- `user.credit`: 1 time
|
||||
- `feature.price`: 3 times (redundant!)
|
||||
- **Total**: 6 fetches
|
||||
|
||||
**New System Value Fetches:**
|
||||
- `user.balance`: 1 time (cached)
|
||||
- `user.credit`: 1 time (cached)
|
||||
- `feature.price`: 1 time (cached)
|
||||
- **Total**: 3 fetches (50% reduction)
|
||||
|
||||
## Implementation Guidelines
|
||||
|
||||
### 1. **Using ValueContext**
|
||||
|
||||
```javascript
|
||||
// Single evaluation with context
|
||||
const valueContext = new ValueContext(arbiter);
|
||||
const result = ruleEvaluator.evaluateRule(/* ... */, { valueContext });
|
||||
|
||||
// Batch evaluation (automatic shared context)
|
||||
const results = ruleEvaluator.batchEvaluateRules(queries);
|
||||
|
||||
// Performance monitoring
|
||||
const stats = valueContext.getStats();
|
||||
console.log(`Cache hit rate: ${stats.hitRate * 100}%`);
|
||||
```
|
||||
|
||||
### 2. **Adding Value Collection to Custom Rules**
|
||||
|
||||
```javascript
|
||||
export class CustomRule extends BaseRule {
|
||||
_evaluateRule(userId, userKey, objectId, objectKey, rule, visited, currentRelation, options) {
|
||||
const { valueContext } = options;
|
||||
|
||||
// Collect values during evaluation
|
||||
const collectedValues = [];
|
||||
|
||||
// ... rule logic ...
|
||||
|
||||
// Add values you've collected
|
||||
const collectedValue = this._createCollectedValue(
|
||||
value, possibility, path, source, metadata
|
||||
);
|
||||
collectedValues.push(collectedValue);
|
||||
|
||||
return this._createStandardResult(authResult, collectedValues);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **Performance Monitoring**
|
||||
|
||||
```javascript
|
||||
// Enable value context stats in production
|
||||
const result = ruleEvaluator.evaluateRule(/* ... */, {
|
||||
valueContext,
|
||||
trackPerformance: true
|
||||
});
|
||||
|
||||
const stats = ruleEvaluator.getValueContextStats({ valueContext });
|
||||
logger.info('Rule evaluation performance', {
|
||||
cacheHitRate: stats.hitRate,
|
||||
fetchReduction: stats.fetchCount,
|
||||
executionTime: result.executionTime
|
||||
});
|
||||
```
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Backward Compatibility
|
||||
- ✅ **Complete**: All optimizations work alongside existing code
|
||||
- ✅ **Complete**: No breaking changes to existing rule configurations
|
||||
- ✅ **Complete**: Automatic fallback to original logic when ValueContext unavailable
|
||||
|
||||
### Phase 2: Gradual Adoption
|
||||
- **Recommended**: Use ValueContext in new rule evaluations
|
||||
- **Recommended**: Enable for batch operations (automatic)
|
||||
- **Optional**: Retrofit existing custom rules to use ValueContext
|
||||
|
||||
### Phase 3: Full Optimization
|
||||
- **Future**: Require ValueContext for all evaluations
|
||||
- **Future**: Remove fallback extraction logic
|
||||
- **Future**: Add advanced caching strategies (LRU, TTL, etc.)
|
||||
|
||||
## Validation & Testing
|
||||
|
||||
### Correctness Validation
|
||||
- ✅ **Complete**: All optimizations maintain identical results to original system
|
||||
- ✅ **Complete**: Comprehensive test coverage with `ValueOptimizationDemo`
|
||||
- ✅ **Complete**: Edge case handling (missing values, cache misses, etc.)
|
||||
|
||||
### Performance Testing
|
||||
- ✅ **Available**: Demo shows 50%+ fetch reduction in typical scenarios
|
||||
- ✅ **Available**: Cache hit rates consistently above 70%
|
||||
- ✅ **Available**: Performance tracking and monitoring built-in
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### 1. **Advanced Caching**
|
||||
- **LRU Eviction**: Limit memory usage in long-running processes
|
||||
- **TTL Support**: Expire stale values automatically
|
||||
- **Persistent Cache**: Cross-evaluation value persistence
|
||||
|
||||
### 2. **Smart Prefetching**
|
||||
- **Dependency Analysis**: Pre-fetch values based on rule structure
|
||||
- **Batch Loading**: Group value fetches by entity/relation patterns
|
||||
- **Predictive Caching**: Learn from evaluation patterns
|
||||
|
||||
### 3. **Distributed Caching**
|
||||
- **Redis Integration**: Share ValueContext across service instances
|
||||
- **Cluster Coordination**: Synchronized cache invalidation
|
||||
- **Partitioning**: Shard value cache by entity patterns
|
||||
|
||||
## Conclusion
|
||||
|
||||
The ValueContext optimization system provides:
|
||||
|
||||
1. **🚀 Performance**: 50-90% reduction in redundant value fetches
|
||||
2. **💡 Intelligence**: Smart inference decisions based on available values
|
||||
3. **🔄 Compatibility**: Zero breaking changes to existing code
|
||||
4. **📊 Observability**: Built-in performance monitoring and stats
|
||||
5. **🛡️ Reliability**: Maintained result consistency with comprehensive testing
|
||||
|
||||
This optimization eliminates the core inefficiencies in value handling while maintaining full backward compatibility and providing a foundation for future enhancements.
|
||||
Reference in New Issue
Block a user