package resolver import ( "encoding/json" "os" "strconv" "strings" ) func ReadLinesAllowMissing(path string) []string { data, err := os.ReadFile(path) if err != nil { return nil } return strings.Split(strings.ReplaceAll(string(data), "\r\n", "\n"), "\n") } func LoadJSONMap(path string) map[string]any { data, err := os.ReadFile(path) if err != nil { return map[string]any{} } var out map[string]any if err := json.Unmarshal(data, &out); err != nil { return map[string]any{} } return out } func SaveJSON(data any, path string) { tmp := path + ".tmp" b, err := json.MarshalIndent(data, "", " ") if err != nil { return } _ = os.WriteFile(tmp, b, 0o644) _ = os.Rename(tmp, path) } func parseAnyInt(raw any) (int, bool) { switch v := raw.(type) { case int: return v, true case int64: return int(v), true case float64: return int(v), true case json.Number: n, err := v.Int64() if err != nil { return 0, false } return int(n), true case string: s := strings.TrimSpace(v) if s == "" { return 0, false } n, err := strconv.Atoi(s) if err != nil { return 0, false } return n, true default: return 0, false } } func LoadResolverPrecheckLastRun(path string) int { m := LoadJSONMap(path) if len(m) == 0 { return 0 } v, ok := parseAnyInt(m["last_run"]) if !ok || v <= 0 { return 0 } return v } func LoadResolverLiveBatchTarget(path string, fallback, minV, maxV int) int { if fallback < minV { fallback = minV } if fallback > maxV { fallback = maxV } m := LoadJSONMap(path) if len(m) == 0 { return fallback } raw := m["live_batch_next_target"] if raw == nil { raw = m["live_batch_target"] } v, ok := parseAnyInt(raw) if !ok || v <= 0 { return fallback } if v < minV { v = minV } if v > maxV { v = maxV } return v } func LoadResolverLiveBatchNXHeavyPct(path string, fallback, minV, maxV int) int { if fallback < minV { fallback = minV } if fallback > maxV { fallback = maxV } m := LoadJSONMap(path) if len(m) == 0 { return fallback } raw := m["live_batch_nxheavy_next_pct"] if raw == nil { raw = m["live_batch_nxheavy_pct"] } v, ok := parseAnyInt(raw) if !ok { return fallback } if v < minV { v = minV } if v > maxV { v = maxV } return v }