001package gudusoft.gsqlparser.sqlenv.catalog; 002 003import java.util.concurrent.atomic.AtomicLong; 004 005/** 006 * Catalog 监控指标(Phase 2: Read Switching) 007 * 008 * <p>用于监控读取路径的命中率和回退率,帮助评估新实现的质量。 009 * 010 * @since 3.2.0 (Phase 2) 011 */ 012public class CatalogMetrics { 013 014 private final AtomicLong newHitCount = new AtomicLong(0); 015 private final AtomicLong missCount = new AtomicLong(0); 016 private final AtomicLong fallbackCount = new AtomicLong(0); 017 private final AtomicLong legacyHitCount = new AtomicLong(0); 018 019 /** 020 * 记录新实现命中 021 */ 022 public void recordNewHit() { 023 newHitCount.incrementAndGet(); 024 } 025 026 /** 027 * 记录未找到(miss) 028 */ 029 public void recordMiss() { 030 missCount.incrementAndGet(); 031 } 032 033 /** 034 * 记录回退到旧实现 035 */ 036 public void recordFallback() { 037 fallbackCount.incrementAndGet(); 038 } 039 040 /** 041 * 记录旧实现命中 042 */ 043 public void recordLegacyHit() { 044 legacyHitCount.incrementAndGet(); 045 } 046 047 /** 048 * 计算新实现命中率 049 * 050 * @return 命中率 (0.0 到 1.0) 051 */ 052 public double getNewHitRate() { 053 long total = newHitCount.get() + missCount.get() + fallbackCount.get(); 054 if (total == 0) { 055 return 0.0; 056 } 057 return (double) newHitCount.get() / total; 058 } 059 060 /** 061 * 计算回退率 062 * 063 * @return 回退率 (0.0 到 1.0) 064 */ 065 public double getFallbackRate() { 066 long total = newHitCount.get() + missCount.get() + fallbackCount.get(); 067 if (total == 0) { 068 return 0.0; 069 } 070 return (double) fallbackCount.get() / total; 071 } 072 073 /** 074 * 计算总命中率(包括新实现和回退) 075 * 076 * @return 总命中率 (0.0 到 1.0) 077 */ 078 public double getTotalHitRate() { 079 long total = newHitCount.get() + missCount.get() + fallbackCount.get(); 080 if (total == 0) { 081 return 0.0; 082 } 083 return (double) (newHitCount.get() + fallbackCount.get()) / total; 084 } 085 086 /** 087 * 获取新实现命中数 088 * 089 * @return 命中数 090 */ 091 public long getNewHitCount() { 092 return newHitCount.get(); 093 } 094 095 /** 096 * 获取未找到数 097 * 098 * @return 未找到数 099 */ 100 public long getMissCount() { 101 return missCount.get(); 102 } 103 104 /** 105 * 获取回退数 106 * 107 * @return 回退数 108 */ 109 public long getFallbackCount() { 110 return fallbackCount.get(); 111 } 112 113 /** 114 * 获取旧实现命中数 115 * 116 * @return 旧实现命中数 117 */ 118 public long getLegacyHitCount() { 119 return legacyHitCount.get(); 120 } 121 122 /** 123 * 获取总操作数 124 * 125 * @return 总操作数 126 */ 127 public long getTotalOperations() { 128 return newHitCount.get() + missCount.get() + fallbackCount.get() + legacyHitCount.get(); 129 } 130 131 /** 132 * 重置所有计数器 133 */ 134 public void reset() { 135 newHitCount.set(0); 136 missCount.set(0); 137 fallbackCount.set(0); 138 legacyHitCount.set(0); 139 } 140 141 /** 142 * 生成监控报告 143 * 144 * @return 报告字符串 145 */ 146 public String generateReport() { 147 StringBuilder sb = new StringBuilder(); 148 sb.append("CatalogMetrics Report:\n"); 149 sb.append("==================================================\n"); 150 sb.append(String.format("New Implementation Hits: %,d%n", newHitCount.get())); 151 sb.append(String.format("Misses (not found): %,d%n", missCount.get())); 152 sb.append(String.format("Fallbacks to Legacy: %,d%n", fallbackCount.get())); 153 sb.append(String.format("Legacy Direct Hits: %,d%n", legacyHitCount.get())); 154 sb.append("==================================================\n"); 155 sb.append(String.format("Total Operations: %,d%n", getTotalOperations())); 156 sb.append(String.format("New Hit Rate: %.2f%%%n", getNewHitRate() * 100)); 157 sb.append(String.format("Fallback Rate: %.2f%%%n", getFallbackRate() * 100)); 158 sb.append(String.format("Total Hit Rate: %.2f%%%n", getTotalHitRate() * 100)); 159 sb.append("==================================================\n"); 160 161 // Quality assessment 162 if (getNewHitRate() >= 0.99) { 163 sb.append("✅ Quality: EXCELLENT (Ready for Phase 3)\n"); 164 } else if (getNewHitRate() >= 0.95) { 165 sb.append("⚠️ Quality: GOOD (Minor issues, investigate misses)\n"); 166 } else if (getNewHitRate() >= 0.90) { 167 sb.append("⚠️ Quality: ACCEPTABLE (Some issues, review needed)\n"); 168 } else { 169 sb.append("❌ Quality: POOR (Significant issues, rollback recommended)\n"); 170 } 171 172 return sb.toString(); 173 } 174 175 /** 176 * 检查是否准备好进入 Phase 3 177 * 178 * @return true 如果新实现命中率 >= 99% 179 */ 180 public boolean isReadyForPhase3() { 181 return getNewHitRate() >= 0.99 && getFallbackRate() < 0.01; 182 } 183 184 /** 185 * 生成简短状态摘要 186 * 187 * @return 状态摘要 188 */ 189 public String getShortSummary() { 190 return String.format("NewHit=%d, Miss=%d, Fallback=%d, HitRate=%.2f%%", 191 newHitCount.get(), missCount.get(), fallbackCount.get(), getNewHitRate() * 100); 192 } 193}