Skip to content

Commit

Permalink
sort rules by name
Browse files Browse the repository at this point in the history
Sort rules by name, so they're checked in alphabetical order.

This way, you can place deny rules at the top of the list to get better
performance, since it won't check the rest of the rules.

Discussion: #36
  • Loading branch information
gustavo-iniguez-goya committed Oct 21, 2020
1 parent cc75289 commit c2ee610
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions daemon/rule/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"path"
"path/filepath"
"sort"
"strings"
"sync"
"time"
Expand All @@ -24,6 +25,7 @@ type Loader struct {
sync.RWMutex
path string
rules map[string]*Rule
rulesKeys []string
watcher *fsnotify.Watcher
liveReload bool
liveReloadRunning bool
Expand Down Expand Up @@ -103,6 +105,8 @@ func (l *Loader) Load(path string) error {
}
}

l.sortRules()

if l.liveReload && l.liveReloadRunning == false {
go l.liveReloadWorker()
}
Expand Down Expand Up @@ -167,6 +171,14 @@ func (l *Loader) setUniqueName(rule *Rule) {
}
}

func (l *Loader) sortRules() {
l.rulesKeys = make([]string, 0, len(l.rules))
for k := range l.rules {
l.rulesKeys = append(l.rulesKeys, k)
}
sort.Strings(l.rulesKeys)
}

func (l *Loader) addUserRule(rule *Rule) {
if rule.Duration == Once {
return
Expand All @@ -184,6 +196,7 @@ func (l *Loader) replaceUserRule(rule *Rule) {
}
}
l.rules[rule.Name] = rule
l.sortRules()
l.Unlock()

if rule.Duration == Restart || rule.Duration == Always {
Expand All @@ -198,6 +211,7 @@ func (l *Loader) replaceUserRule(rule *Rule) {
time.AfterFunc(tTime, func() {
l.Lock()
delete(l.rules, rule.Name)
l.sortRules()
l.Unlock()
})
}
Expand Down Expand Up @@ -248,10 +262,17 @@ func (l *Loader) Delete(ruleName string) error {
defer l.Unlock()

rule := l.rules[ruleName]
if rule == nil {
return nil
}

delete(l.rules, ruleName)
if rule == nil || rule.Duration != Always {
l.sortRules()

if rule.Duration != Always {
return nil
}

log.Info("Delete() rule: ", rule)
path := fmt.Sprint(l.path, "/", ruleName, ".json")
return os.Remove(path)
Expand All @@ -262,7 +283,11 @@ func (l *Loader) FindFirstMatch(con *conman.Connection) (match *Rule) {
l.RLock()
defer l.RUnlock()

for _, rule := range l.rules {
for _, ruleIdx := range l.rulesKeys {
rule, valid := l.rules[ruleIdx]
if !valid {
continue
}
// if we already have a match, we don't need
// to evaluate 'allow' rules anymore, we only
// need to make sure there's no 'deny' rule
Expand Down

0 comments on commit c2ee610

Please sign in to comment.