Simplify pagination implementation

* Eliminate the need to sort the rule groups.

Signed-off-by: Raphael Silva <rapphil@gmail.com>
This commit is contained in:
Raphael Silva 2024-07-04 06:19:44 +00:00
parent 57592168b0
commit 71c9dfa4aa
2 changed files with 22 additions and 41 deletions

View file

@ -1425,13 +1425,19 @@ func (api *API) rules(r *http.Request) apiFuncResult {
return invalidParamError(parseErr.err, parseErr.parameter)
}
if paginationRequest != nil {
sort.Sort(GroupStateDescs(ruleGroups))
}
rgs := make([]*RuleGroup, 0, len(ruleGroups))
foundToken := false
for _, grp := range ruleGroups {
if paginationRequest != nil && paginationRequest.NextToken != "" && !foundToken {
if paginationRequest.NextToken == getRuleGroupNextToken(grp.File(), grp.Name()) {
foundToken = true
} else {
continue
}
}
if len(rgSet) > 0 {
if _, ok := rgSet[grp.Name()]; !ok {
continue
@ -1444,12 +1450,6 @@ func (api *API) rules(r *http.Request) apiFuncResult {
}
}
// Skip the rule group if the next token is set and hasn't arrived at the nextToken item yet.
groupID := getRuleGroupNextToken(grp.File(), grp.Name())
if paginationRequest != nil && len(paginationRequest.NextToken) > 0 && paginationRequest.NextToken >= groupID {
continue
}
apiRuleGroup := &RuleGroup{
Name: grp.Name(),
File: grp.File(),
@ -1526,12 +1526,20 @@ func (api *API) rules(r *http.Request) apiFuncResult {
if len(apiRuleGroup.Rules) > 0 {
rgs = append(rgs, apiRuleGroup)
}
if paginationRequest != nil && len(rgs) == int(paginationRequest.MaxRuleGroups+1) {
break
}
}
if paginationRequest != nil {
returnGroups, nextToken := TruncateGroupInfos(rgs, int(paginationRequest.MaxRuleGroups))
res.NextToken = nextToken
res.RuleGroups = returnGroups
if len(rgs) == int(paginationRequest.MaxRuleGroups+1) {
nextRg := rgs[paginationRequest.MaxRuleGroups]
res.NextToken = getRuleGroupNextToken(nextRg.File, nextRg.Name)
res.RuleGroups = rgs[:paginationRequest.MaxRuleGroups]
} else {
res.RuleGroups = rgs
}
return apiFuncResult{res, nil, nil, nil}
}
@ -1584,25 +1592,6 @@ func parseListRulesPaginationRequest(r *http.Request) (*listRulesPaginationReque
return nil, nil
}
func TruncateGroupInfos(groupInfos []*RuleGroup, maxRuleGroups int) ([]*RuleGroup, string) {
var returnPaginationToken string
returnGroupDescs := make([]*RuleGroup, 0, len(groupInfos))
for _, groupInfo := range groupInfos {
// Add the rule group to the return slice if the maxRuleGroups is not hit
if maxRuleGroups < 0 || len(returnGroupDescs) < maxRuleGroups {
returnGroupDescs = append(returnGroupDescs, groupInfo)
continue
}
// Return the next token if there are more aggregation groups
if maxRuleGroups > 0 && len(returnGroupDescs) == maxRuleGroups {
returnPaginationToken = getRuleGroupNextToken(returnGroupDescs[maxRuleGroups-1].File, returnGroupDescs[maxRuleGroups-1].Name)
break
}
}
return returnGroupDescs, returnPaginationToken
}
func getRuleGroupNextToken(file, group string) string {
h := sha1.New()
h.Write([]byte(file + ";" + group))
@ -2005,11 +1994,3 @@ func parseLimitParam(limitStr string) (limit int, err error) {
return limit, nil
}
type GroupStateDescs []*rules.Group
func (g GroupStateDescs) Swap(i, j int) { g[i], g[j] = g[j], g[i] }
func (g GroupStateDescs) Less(i, j int) bool {
return getRuleGroupNextToken(g[i].File(), g[i].Name()) < getRuleGroupNextToken(g[j].File(), g[j].Name())
}
func (g GroupStateDescs) Len() int { return len(g) }

View file

@ -2407,7 +2407,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, es storage.E
"maxRuleGroups": []string{"1"},
},
response: &RuleDiscovery{
NextToken: getRuleGroupNextToken("/path/to/file", "grp"),
NextToken: getRuleGroupNextToken("/path/to/file", "grp2"),
RuleGroups: []*RuleGroup{
{
Name: "grp",