mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-24 17:36:47 +08:00
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 <futurehua@outlook.com>
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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, ",")
|
||||
|
||||
@@ -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++
|
||||
}
|
||||
|
||||
@@ -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] {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -133,14 +133,8 @@ func (e *novitaThinkExtractor) Feed(chunk string) []novitaThinkSegment {
|
||||
// (max marker length - 1) trailing bytes so we don't
|
||||
// emit "<thin" as content when the next chunk completes
|
||||
// it to "<think>".
|
||||
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:], "<") {
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user