/** * Analysis of which rules use reachability optimization */ import { test } from 'node:test'; import assert from 'node:assert/strict'; import { BigGraphGenerator } from '../helpers/big-graph-generator.js'; test('analyzes which rules use reachability optimization', async () => { if (process.env.TEST_DEBUG === '1') console.log('šŸ” Analyzing which rules use reachability optimization...'); const generator = new BigGraphGenerator(); const graphData = generator.generateGraph('enterprise'); const arbiter = generator.loadIntoArbiter(graphData); // Initialize reachability checker await arbiter.initializeReachabilityChecker({ strategy: 'auto', twoHopOptions: {}, treeCoverOptions: {} }); // Get initial reachability stats const initialStats = arbiter.getReachabilityStats(); if (process.env.TEST_DEBUG === '1') console.log(`Initial reachability stats: ${initialStats.totalQueries} queries`); // Test different rule types const testCases = [ { name: 'DirectRule', relation: 'can_read', description: 'Direct relations (should use fast path)' }, { name: 'ChainRule', relation: 'can_read_via_role', description: 'Chain relations (should use reachability)' }, { name: 'MultiHopRule', relation: 'can_access_multi_hop', description: 'Multi-hop relations (should use reachability)' }, { name: 'ParentRule', relation: 'can_read', // Parent rule uses direct relations description: 'Parent relations (might use reachability)' }, { name: 'TupleToUsersetRule', relation: 'can_read', description: 'Tuple-to-userset relations (might use reachability)' } ]; const results = {}; for (const testCase of testCases) { if (process.env.TEST_DEBUG === '1') console.log(`\\n=== TESTING ${testCase.name} ===`); if (process.env.TEST_DEBUG === '1') console.log(`Description: ${testCase.description}`); // Reset reachability stats const beforeStats = arbiter.getReachabilityStats(); // Test the rule const testRelations = graphData.relations.filter(r => r.src.startsWith('user:') && r.dst.startsWith('doc:') && r.relation === 'can_read' ).slice(0, 3); const startTime = Date.now(); let queryCount = 0; const latencies = []; for (const relation of testRelations) { const queryStart = process.hrtime.bigint(); try { const result = arbiter.check(relation.src, testCase.relation, relation.dst); const queryEnd = process.hrtime.bigint(); const latency = Number(queryEnd - queryStart) / 1000000; latencies.push(latency); queryCount++; } catch (error) { queryCount++; } } const duration = Date.now() - startTime; const qps = (queryCount / duration) * 1000; const avgLatency = latencies.length > 0 ? latencies.reduce((a, b) => a + b, 0) / latencies.length : 0; // Get reachability stats after const afterStats = arbiter.getReachabilityStats(); const reachabilityQueries = afterStats.totalQueries - beforeStats.totalQueries; const twoHopHits = afterStats.twoHopHits - beforeStats.twoHopHits; const treeCoverHits = afterStats.treeCoverHits - beforeStats.treeCoverHits; const fallbackQueries = afterStats.fallbackQueries - beforeStats.fallbackQueries; results[testCase.name] = { qps, avgLatency, reachabilityQueries, twoHopHits, treeCoverHits, fallbackQueries, usesReachability: reachabilityQueries > 0 }; if (process.env.TEST_DEBUG === '1') console.log(` QPS: ${qps.toFixed(2)}`); if (process.env.TEST_DEBUG === '1') console.log(` Avg Latency: ${avgLatency.toFixed(3)}ms`); if (process.env.TEST_DEBUG === '1') console.log(` Reachability Queries: ${reachabilityQueries}`); if (process.env.TEST_DEBUG === '1') console.log(` TwoHop Hits: ${twoHopHits}`); if (process.env.TEST_DEBUG === '1') console.log(` TreeCover Hits: ${treeCoverHits}`); if (process.env.TEST_DEBUG === '1') console.log(` Fallback Queries: ${fallbackQueries}`); if (process.env.TEST_DEBUG === '1') console.log(` Uses Reachability: ${reachabilityQueries > 0 ? 'āœ… YES' : 'āŒ NO'}`); } // Analysis if (process.env.TEST_DEBUG === '1') console.log('\\n=== REACHABILITY OPTIMIZATION ANALYSIS ==='); const rulesUsingReachability = Object.entries(results) .filter(([name, result]) => result.usesReachability) .map(([name, result]) => name); const rulesNotUsingReachability = Object.entries(results) .filter(([name, result]) => !result.usesReachability) .map(([name, result]) => name); if (process.env.TEST_DEBUG === '1') console.log(`\\nāœ… Rules USING reachability optimization:`); rulesUsingReachability.forEach(rule => { const result = results[rule]; if (process.env.TEST_DEBUG === '1') console.log(` - ${rule}: ${result.reachabilityQueries} queries, ${result.treeCoverHits} tree-cover hits`); }); if (process.env.TEST_DEBUG === '1') console.log(`\\nāŒ Rules NOT using reachability optimization:`); rulesNotUsingReachability.forEach(rule => { const result = results[rule]; if (process.env.TEST_DEBUG === '1') console.log(` - ${rule}: ${result.qps.toFixed(2)} QPS, ${result.avgLatency.toFixed(3)}ms avg`); }); // Performance comparison if (process.env.TEST_DEBUG === '1') console.log(`\\n=== PERFORMANCE COMPARISON ===`); const reachabilityRules = rulesUsingReachability.map(rule => ({ name: rule, ...results[rule] })); const nonReachabilityRules = rulesNotUsingReachability.map(rule => ({ name: rule, ...results[rule] })); if (reachabilityRules.length > 0) { const avgReachabilityQPS = reachabilityRules.reduce((sum, rule) => sum + rule.qps, 0) / reachabilityRules.length; if (process.env.TEST_DEBUG === '1') console.log(`Average QPS for rules WITH reachability: ${avgReachabilityQPS.toFixed(2)}`); } if (nonReachabilityRules.length > 0) { const avgNonReachabilityQPS = nonReachabilityRules.reduce((sum, rule) => sum + rule.qps, 0) / nonReachabilityRules.length; if (process.env.TEST_DEBUG === '1') console.log(`Average QPS for rules WITHOUT reachability: ${avgNonReachabilityQPS.toFixed(2)}`); } // Recommendations if (process.env.TEST_DEBUG === '1') console.log(`\\n=== RECOMMENDATIONS ===`); if (rulesNotUsingReachability.length > 0) { if (process.env.TEST_DEBUG === '1') console.log(`Consider optimizing these rules with reachability indexes:`); rulesNotUsingReachability.forEach(rule => { if (process.env.TEST_DEBUG === '1') console.log(` - ${rule}: Could benefit from reachability optimization`); }); } else { if (process.env.TEST_DEBUG === '1') console.log(`All tested rules are using reachability optimization! šŸŽ‰`); } // Final stats const finalStats = arbiter.getReachabilityStats(); if (process.env.TEST_DEBUG === '1') console.log(`\\n=== FINAL REACHABILITY STATS ===`); if (process.env.TEST_DEBUG === '1') console.log(`Total queries: ${finalStats.totalQueries}`); if (process.env.TEST_DEBUG === '1') console.log(`TwoHop hits: ${finalStats.twoHopHits}`); if (process.env.TEST_DEBUG === '1') console.log(`TreeCover hits: ${finalStats.treeCoverHits}`); if (process.env.TEST_DEBUG === '1') console.log(`Fallback queries: ${finalStats.fallbackQueries}`); if (process.env.TEST_DEBUG === '1') console.log(`Strategy: ${finalStats.strategy}`); });