From bd355deaa9953f9dbd488f275787ab8f20891818 Mon Sep 17 00:00:00 2001 From: futurehua Date: Fri, 24 Jul 2026 15:33:02 +0800 Subject: [PATCH] refactor: use the built-in max/min to simplify the code (#17059) ### Summary In Go 1.21, the standard library includes built-in [max/min](https://pkg.go.dev/builtin@go1.21.0#max) function, which can greatly simplify the code. Signed-off-by: futurehua --- .../agent/component/io/pdf_writer_test.go | 7 ------- internal/agent/tool/duckduckgo.go | 7 ------- internal/agent/workflowx/loop.go | 5 +---- internal/cli/filesystem/dataset.go | 7 ------- .../filesystem/skill_hub/source/clawhub.go | 7 ------- internal/common/format.go | 5 +---- .../deepdoc/parser/pdf/table/table_layout.go | 5 +---- .../deepdoc/parser/pdf/table/table_post.go | 5 +---- internal/engine/elasticsearch/chunk.go | 20 ++++--------------- internal/engine/elasticsearch/chunk_test.go | 5 +---- internal/engine/elasticsearch/metadata.go | 5 +---- internal/engine/infinity/chunk.go | 5 +---- internal/engine/infinity/metadata.go | 5 +---- internal/entity/models/novita.go | 10 ++-------- internal/entity/models/paddleocr.go | 5 +---- .../dynamictool/toolsearch/toolsearch.go | 5 +---- internal/harness/graph/task/decorator.go | 5 +---- internal/harness/graph/types/types.go | 10 ++-------- internal/harness/metrics/aggregator.go | 5 +---- internal/harness/replay/replay.go | 5 +---- .../compilation/extractor/ner_relation.go | 14 ------------- internal/parser/chunk/split.go | 10 ++-------- internal/service/nlp/query_builder.go | 5 +---- internal/service/nlp/retrieval.go | 5 +---- internal/storage/minio_test.go | 8 -------- internal/utility/captcha_png.go | 5 +---- internal/utility/convert.go | 5 +---- 27 files changed, 27 insertions(+), 158 deletions(-) diff --git a/internal/agent/component/io/pdf_writer_test.go b/internal/agent/component/io/pdf_writer_test.go index 5517567462..7ae221e646 100644 --- a/internal/agent/component/io/pdf_writer_test.go +++ b/internal/agent/component/io/pdf_writer_test.go @@ -116,10 +116,3 @@ func requirePDFLatinFont(t *testing.T) { t.Skip("no local Latin PDF font available") } } - -func min(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/internal/agent/tool/duckduckgo.go b/internal/agent/tool/duckduckgo.go index efc0af0dc6..c9a8ffe90a 100644 --- a/internal/agent/tool/duckduckgo.go +++ b/internal/agent/tool/duckduckgo.go @@ -565,13 +565,6 @@ func normalizeWhitespace(s string) string { return strings.Join(strings.Fields(strings.TrimSpace(s)), " ") } -func min(a, b int) int { - if a < b { - return a - } - return b -} - func duckduckgoJSON(env duckduckgoEnvelope) string { b, err := json.Marshal(env) if err != nil { diff --git a/internal/agent/workflowx/loop.go b/internal/agent/workflowx/loop.go index 90b64da5fd..5bee91237a 100644 --- a/internal/agent/workflowx/loop.go +++ b/internal/agent/workflowx/loop.go @@ -584,10 +584,7 @@ func runLoopStream[T any]( // size the slice: maxIterations is always set (default or // user-supplied), so a bound of maxIterations - snap.startIteration + 1 // is safe and tight. - remaining := options.maxIterations - snap.startIteration + 1 - if remaining < 1 { - remaining = 1 - } + remaining := max(options.maxIterations-snap.startIteration+1, 1) streamMode := snap.streamMode streamReaders := make([]*schema.StreamReader[T], 0, remaining) diff --git a/internal/cli/filesystem/dataset.go b/internal/cli/filesystem/dataset.go index dc201ef00f..8383743412 100644 --- a/internal/cli/filesystem/dataset.go +++ b/internal/cli/filesystem/dataset.go @@ -711,13 +711,6 @@ func getString(v interface{}) string { return fmt.Sprintf("%v", v) } -func min(a, b int) int { - if a < b { - return a - } - return b -} - func getFloat(v interface{}) float64 { if v == nil { return 0 diff --git a/internal/cli/filesystem/skill_hub/source/clawhub.go b/internal/cli/filesystem/skill_hub/source/clawhub.go index d0b2f816f0..a8c84f0a10 100644 --- a/internal/cli/filesystem/skill_hub/source/clawhub.go +++ b/internal/cli/filesystem/skill_hub/source/clawhub.go @@ -914,10 +914,3 @@ func isTextContent(data []byte) bool { // Check for null bytes (indicates binary) return !slices.Contains(data, 0) } - -func min(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/internal/common/format.go b/internal/common/format.go index a61724b721..1aa4adc9a4 100644 --- a/internal/common/format.go +++ b/internal/common/format.go @@ -109,10 +109,7 @@ func FormatNumber(n int64) string { s := fmt.Sprintf("%d", n) parts := []string{} for i := len(s); i > 0; i -= 3 { - start := i - 3 - if start < 0 { - start = 0 - } + start := max(i-3, 0) parts = append([]string{s[start:i]}, parts...) } return strings.Join(parts, ",") diff --git a/internal/deepdoc/parser/pdf/table/table_layout.go b/internal/deepdoc/parser/pdf/table/table_layout.go index ec4f5bcb7d..e4f8797403 100644 --- a/internal/deepdoc/parser/pdf/table/table_layout.go +++ b/internal/deepdoc/parser/pdf/table/table_layout.go @@ -47,10 +47,7 @@ func layoutCleanup(cells []pdf.TSRCell, boxes []pdf.TextBox, far int, thr float6 i := 0 for i+1 < len(out) { j := i + 1 - limit := i + far - if limit > len(out) { - limit = len(out) - } + limit := min(i+far, len(out)) for j < limit && (out[i].Label != "" && out[i].Label != out[j].Label || notOverlapped(out[i], out[j])) { j++ } diff --git a/internal/deepdoc/parser/pdf/table/table_post.go b/internal/deepdoc/parser/pdf/table/table_post.go index 2acaf74031..0ce7066554 100644 --- a/internal/deepdoc/parser/pdf/table/table_post.go +++ b/internal/deepdoc/parser/pdf/table/table_post.go @@ -19,10 +19,7 @@ func FilterBoxesByRemoveSet(boxes []pdf.TextBox, removeSet map[int]bool) []pdf.T } // Pre-allocate: estimate final size to avoid resizing // Use max to prevent negative capacity when len(removeSet) > len(boxes) - estimatedCap := len(boxes) - len(removeSet) - if estimatedCap < 0 { - estimatedCap = 0 - } + estimatedCap := max(len(boxes)-len(removeSet), 0) out := make([]pdf.TextBox, 0, estimatedCap) for i, b := range boxes { if !removeSet[i] { diff --git a/internal/engine/elasticsearch/chunk.go b/internal/engine/elasticsearch/chunk.go index 74ab265d55..6455d23716 100644 --- a/internal/engine/elasticsearch/chunk.go +++ b/internal/engine/elasticsearch/chunk.go @@ -959,10 +959,7 @@ func (e *elasticsearchEngine) Search(ctx context.Context, req *types.SearchReque return nil, fmt.Errorf("index names cannot be empty") } - offset := req.Offset - if offset < 0 { - offset = 0 - } + offset := max(req.Offset, 0) limit := req.Limit if limit <= 0 { limit = 30 @@ -1353,10 +1350,7 @@ func searchAfterPaginate( // Skip phase: walk past `offset` hits without retaining them. remainingSkip := offset for remainingSkip > 0 { - batch := remainingSkip - if batch > common.SearchAfterBatchSize { - batch = common.SearchAfterBatchSize - } + batch := min(remainingSkip, common.SearchAfterBatchSize) resp, err := fetch(ctx, baseQuery, batch, cursor, firstCall) firstCall = false @@ -1390,10 +1384,7 @@ func searchAfterPaginate( // target) regardless of how many we asked for in this iteration. for collectedTake < limit { want := limit - collectedTake - batch := want - if batch > common.SearchAfterBatchSize { - batch = common.SearchAfterBatchSize - } + batch := min(want, common.SearchAfterBatchSize) resp, err := fetch(ctx, baseQuery, batch, cursor, firstCall) firstCall = false @@ -2857,10 +2848,7 @@ func calculatePagination(page, size, topK int) (int, int) { window := rerankWindow(size, topK) - offset := (page - 1) * window - if offset < 0 { - offset = 0 - } + offset := max((page-1)*window, 0) return offset, window } diff --git a/internal/engine/elasticsearch/chunk_test.go b/internal/engine/elasticsearch/chunk_test.go index e8a6c140c7..c1f271ec35 100644 --- a/internal/engine/elasticsearch/chunk_test.go +++ b/internal/engine/elasticsearch/chunk_test.go @@ -459,10 +459,7 @@ func paginate(total, size, topK int) (window, capN int, surfaced []int) { block = append(block, i) } begin := globalOffset % window - end := begin + size - if end > len(block) { - end = len(block) - } + end := min(begin+size, len(block)) surfaced = append(surfaced, block[begin:end]...) } return window, capN, surfaced diff --git a/internal/engine/elasticsearch/metadata.go b/internal/engine/elasticsearch/metadata.go index a7395f5dd0..2d231fbe96 100644 --- a/internal/engine/elasticsearch/metadata.go +++ b/internal/engine/elasticsearch/metadata.go @@ -564,10 +564,7 @@ func (e *elasticsearchEngine) SearchMetadata(ctx context.Context, req *types.Sea }, nil } - offset := req.Offset - if offset < 0 { - offset = 0 - } + offset := max(req.Offset, 0) limit := req.Limit if limit <= 0 { limit = 30 diff --git a/internal/engine/infinity/chunk.go b/internal/engine/infinity/chunk.go index 30e0b0c564..092b7adb92 100644 --- a/internal/engine/infinity/chunk.go +++ b/internal/engine/infinity/chunk.go @@ -703,10 +703,7 @@ func (e *infinityEngine) Search(ctx context.Context, req *types.SearchRequest) ( pageSize = 30 } - offset := req.Offset - if offset < 0 { - offset = 0 - } + offset := max(req.Offset, 0) db, release, err := e.client.checkoutDatabase(ctx, "chunk.go") if err != nil { diff --git a/internal/engine/infinity/metadata.go b/internal/engine/infinity/metadata.go index 79bd26516a..774612f560 100644 --- a/internal/engine/infinity/metadata.go +++ b/internal/engine/infinity/metadata.go @@ -583,10 +583,7 @@ func (e *infinityEngine) SearchMetadata(ctx context.Context, req *types.SearchMe if pageSize <= 0 { pageSize = 30 } - offset := req.Offset - if offset < 0 { - offset = 0 - } + offset := max(req.Offset, 0) // Build filter from req.Filter var filterStr string diff --git a/internal/entity/models/novita.go b/internal/entity/models/novita.go index 411b8ae658..a3a6b5cd7d 100644 --- a/internal/entity/models/novita.go +++ b/internal/entity/models/novita.go @@ -133,14 +133,8 @@ func (e *novitaThinkExtractor) Feed(chunk string) []novitaThinkSegment { // (max marker length - 1) trailing bytes so we don't // emit "". - reserve := len(marker) - 1 - if len(otherMarker)-1 > reserve { - reserve = len(otherMarker) - 1 - } - safe := len(s) - reserve - if safe < 0 { - safe = 0 - } + reserve := max(len(otherMarker)-1, len(marker)-1) + safe := max(len(s)-reserve, 0) // Don't reserve if the trailing bytes can't possibly be // the start of a tag (no '<' suffix). if safe < len(s) && !strings.Contains(s[safe:], "<") { diff --git a/internal/entity/models/paddleocr.go b/internal/entity/models/paddleocr.go index 77e6c664a7..251f0d15d8 100644 --- a/internal/entity/models/paddleocr.go +++ b/internal/entity/models/paddleocr.go @@ -245,10 +245,7 @@ func (p *PaddleOCRModel) OCRFile(ctx context.Context, modelName *string, content } // Exponential backoff - pollInterval = time.Duration(float64(pollInterval) * pollMultiplier) - if pollInterval > maxPollInterval { - pollInterval = maxPollInterval - } + pollInterval = min(time.Duration(float64(pollInterval)*pollMultiplier), maxPollInterval) select { case <-time.After(pollInterval): diff --git a/internal/harness/core/middlewares/dynamictool/toolsearch/toolsearch.go b/internal/harness/core/middlewares/dynamictool/toolsearch/toolsearch.go index 9c56599e4a..29df38d75d 100644 --- a/internal/harness/core/middlewares/dynamictool/toolsearch/toolsearch.go +++ b/internal/harness/core/middlewares/dynamictool/toolsearch/toolsearch.go @@ -53,10 +53,7 @@ func (m *middleware[M]) ContributeTools(ctx context.Context) []core.Tool { } // Client-side search mode: add search meta-tool + pass some directly tools := []core.Tool{m.newSearchTool()} - passDirect := m.cfg.SearchThreshold / 2 - if passDirect > len(m.cfg.AllTools) { - passDirect = len(m.cfg.AllTools) - } + passDirect := min(m.cfg.SearchThreshold/2, len(m.cfg.AllTools)) tools = append(tools, m.cfg.AllTools[:passDirect]...) return tools } diff --git a/internal/harness/graph/task/decorator.go b/internal/harness/graph/task/decorator.go index c8d27fc047..aed9b6edc4 100644 --- a/internal/harness/graph/task/decorator.go +++ b/internal/harness/graph/task/decorator.go @@ -206,10 +206,7 @@ func (tc *TaskContext) Duration() time.Duration { // calculateBackoff calculates the backoff duration. func calculateBackoff(attempt int, policy *types.RetryPolicy) time.Duration { - backoff := time.Duration(float64(policy.InitialInterval) * math.Pow(policy.BackoffFactor, float64(attempt-1))) - if backoff > policy.MaxInterval { - backoff = policy.MaxInterval - } + backoff := min(time.Duration(float64(policy.InitialInterval)*math.Pow(policy.BackoffFactor, float64(attempt-1))), policy.MaxInterval) if policy.Jitter { backoff = addJitter(backoff) diff --git a/internal/harness/graph/types/types.go b/internal/harness/graph/types/types.go index 3a54b1cd84..b81b6416bc 100644 --- a/internal/harness/graph/types/types.go +++ b/internal/harness/graph/types/types.go @@ -90,17 +90,11 @@ func DefaultRetryPolicy() RetryPolicy { // This is the shared backoff calculation used by both Pregel graph-node retries and // agent-level model-call retries. func (p *RetryPolicy) CalculateBackoff(attempt int) time.Duration { - backoff := time.Duration(float64(p.InitialInterval) * powFloat(p.BackoffFactor, attempt-1)) - if backoff > p.MaxInterval { - backoff = p.MaxInterval - } + backoff := min(time.Duration(float64(p.InitialInterval)*powFloat(p.BackoffFactor, attempt-1)), p.MaxInterval) if p.Jitter { // Subtract up to 50% to spread retry bursts. jitter := time.Duration(float64(backoff) * 0.5 * randFloat()) - backoff = backoff - jitter - if backoff < 0 { - backoff = 0 - } + backoff = max(backoff-jitter, 0) } return backoff } diff --git a/internal/harness/metrics/aggregator.go b/internal/harness/metrics/aggregator.go index 90b256b74d..692d097421 100644 --- a/internal/harness/metrics/aggregator.go +++ b/internal/harness/metrics/aggregator.go @@ -181,10 +181,7 @@ func percentile(sorted []float64, p int) float64 { if len(sorted) == 0 { return 0 } - idx := int(math.Ceil(float64(p)/100.0*float64(len(sorted))) - 1) - if idx < 0 { - idx = 0 - } + idx := max(int(math.Ceil(float64(p)/100.0*float64(len(sorted)))-1), 0) if idx >= len(sorted) { idx = len(sorted) - 1 } diff --git a/internal/harness/replay/replay.go b/internal/harness/replay/replay.go index 91f0f6ac82..30b4fb5dc2 100644 --- a/internal/harness/replay/replay.go +++ b/internal/harness/replay/replay.go @@ -286,10 +286,7 @@ func parsePayload(ev *events.Event, target any) error { // diffEventLists compares original and replayed event lists. func diffEventLists(original, replayed []*events.Event) []EventDivergence { var divergences []EventDivergence - maxLen := len(original) - if len(replayed) > maxLen { - maxLen = len(replayed) - } + maxLen := max(len(replayed), len(original)) for i := 0; i < maxLen; i++ { var orig *events.Event diff --git a/internal/ingestion/compilation/extractor/ner_relation.go b/internal/ingestion/compilation/extractor/ner_relation.go index dcb0cecf08..901cfa3cf8 100644 --- a/internal/ingestion/compilation/extractor/ner_relation.go +++ b/internal/ingestion/compilation/extractor/ner_relation.go @@ -367,20 +367,6 @@ func abs(x int) int { return x } -func min(a, b int) int { - if a < b { - return a - } - return b -} - -func max(a, b int) int { - if a > b { - return a - } - return b -} - // splitSentences splits text into sentence spans [start, end). // Matches Python's: re.finditer(r'[^.!?]+(?:[.!?](?=\s|$))+', text) // Go RE2 lacks lookahead, so this manually identifies sentence boundaries: diff --git a/internal/parser/chunk/split.go b/internal/parser/chunk/split.go index 04c36c123c..ef543c2c84 100644 --- a/internal/parser/chunk/split.go +++ b/internal/parser/chunk/split.go @@ -217,10 +217,7 @@ func (o *SplitOperator) splitByLength(text string) []ChunkData { chunkSize = defaultLengthChunkSize } - overlap := o.overlap - if overlap < 0 { - overlap = 0 - } + overlap := max(o.overlap, 0) if overlap >= chunkSize { overlap = chunkSize - 1 } @@ -233,10 +230,7 @@ func (o *SplitOperator) splitByLength(text string) []ChunkData { var chunks []ChunkData for start := 0; start < len(runes); start += step { - end := start + chunkSize - if end > len(runes) { - end = len(runes) - } + end := min(start+chunkSize, len(runes)) content := string(runes[start:end]) chunks = append(chunks, ChunkData{ diff --git a/internal/service/nlp/query_builder.go b/internal/service/nlp/query_builder.go index 25a16d5a1f..b157cb6f4d 100644 --- a/internal/service/nlp/query_builder.go +++ b/internal/service/nlp/query_builder.go @@ -611,10 +611,7 @@ func (qb *QueryBuilder) Paragraph(contentTks string, keywords []string, keywords // Calculate minimum_should_match (could be used for extra_options in future) _ = 3 if len(allTerms) > 0 { - calc := int(float64(len(allTerms)) / 10.0) - if calc < 3 { - calc = 3 - } + calc := max(int(float64(len(allTerms))/10.0), 3) _ = calc } return &types.MatchTextExpr{ diff --git a/internal/service/nlp/retrieval.go b/internal/service/nlp/retrieval.go index 6fdb9d1139..6a691af523 100644 --- a/internal/service/nlp/retrieval.go +++ b/internal/service/nlp/retrieval.go @@ -573,10 +573,7 @@ func (s *RetrievalService) Search(ctx context.Context, req *RetrievalSearchReque if _, ok := filters["available_int"]; !ok { filters["available_int"] = 1 } - pg := req.Page - 1 - if pg < 0 { - pg = 0 - } + pg := max(req.Page-1, 0) topk := req.Top if topk <= 0 { topk = 1024 diff --git a/internal/storage/minio_test.go b/internal/storage/minio_test.go index 6e677f8305..35365c446a 100644 --- a/internal/storage/minio_test.go +++ b/internal/storage/minio_test.go @@ -631,11 +631,3 @@ func TestMinioStorage_TenantID(t *testing.T) { // Cleanup storage.Remove(bucket, key, tenantID) } - -// min is a helper function to get the minimum of two integers -func min(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/internal/utility/captcha_png.go b/internal/utility/captcha_png.go index 50acd356c7..6715fdd0c8 100644 --- a/internal/utility/captcha_png.go +++ b/internal/utility/captcha_png.go @@ -124,10 +124,7 @@ func RenderCaptchaPNG(text string) []byte { glyphW := captchaGlyphW * captchaPNGScale glyphH := captchaGlyphH * captchaPNGScale - width := captchaSidePadding*2 + len(upper)*glyphW + (len(upper)-1)*captchaCharSpacing - if width < 40 { - width = 40 - } + width := max(captchaSidePadding*2+len(upper)*glyphW+(len(upper)-1)*captchaCharSpacing, 40) height := captchaTopPadding*2 + glyphH + 8 // a bit of headroom for jitter img := image.NewRGBA(image.Rect(0, 0, width, height)) diff --git a/internal/utility/convert.go b/internal/utility/convert.go index 8704fcf0fb..f53dbb5171 100644 --- a/internal/utility/convert.go +++ b/internal/utility/convert.go @@ -133,10 +133,7 @@ func ConvertHexToPositionIntArray(hexStr string) interface{} { // Group by 5 elements var result [][]int for i := 0; i < len(intVals); i += 5 { - end := i + 5 - if end > len(intVals) { - end = len(intVals) - } + end := min(i+5, len(intVals)) result = append(result, intVals[i:end]) }