Better trie implementations

This commit is contained in:
2025-10-08 20:57:13 +02:00
parent 5f0f4aa96b
commit 582163d4be
26 changed files with 2482 additions and 122 deletions

View File

@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
"net/netip"
"path/filepath"
"slices"
"strings"
@@ -20,13 +21,18 @@ type bstoreStorage struct {
}
func OpenBStore(name string) (Storage, error) {
log := logger.StandardLog.Value("database", name)
if !filepath.IsAbs(name) {
var err error
if name, err = filepath.Abs(name); err != nil {
log.Err(err).Error("Opening BoltDB storage failed; invalid path")
return nil, err
}
log = log.Value("database", name)
}
log.Debug("Opening BoltDB storage")
ctx := context.Background()
db, err := bstore.Open(ctx, name, nil,
Group{},
@@ -36,6 +42,7 @@ func OpenBStore(name string) (Storage, error) {
ListGroup{},
)
if err != nil {
log.Err(err).Error("Opening BoltDB storage failed")
return nil, err
}
@@ -47,6 +54,7 @@ func OpenBStore(name string) (Storage, error) {
)
if defaultGroup, err = s.GroupByName("Default"); errors.Is(err, bstore.ErrAbsent) {
log.Debug("Creating default group")
defaultGroup = Group{
Name: "Default",
IsEnabled: true,
@@ -63,6 +71,7 @@ func OpenBStore(name string) (Storage, error) {
FilterFn(func(client Client) bool {
return net.ParseIP(client.IP).Equal(net.ParseIP("0.0.0.0")) && client.Mask == 0
}).Get(); errors.Is(err, bstore.ErrAbsent) {
log.Debug("Creating default IPv4 clients")
defaultClient4 = Client{
Network: "ipv4",
IP: "0.0.0.0",
@@ -83,6 +92,7 @@ func OpenBStore(name string) (Storage, error) {
FilterFn(func(client Client) bool {
return net.ParseIP(client.IP).Equal(net.ParseIP("::")) && client.Mask == 0
}).Get(); errors.Is(err, bstore.ErrAbsent) {
log.Debug("Creating default IPv6 clients")
defaultClient6 = Client{
Network: "ipv6",
IP: "::",
@@ -100,6 +110,7 @@ func OpenBStore(name string) (Storage, error) {
}
// Start updater
log.Trace("Starting list updater")
NewUpdater(s)
return s, nil
@@ -197,7 +208,12 @@ func (s *bstoreStorage) ClientByID(id int64) (Client, error) {
}
func (s *bstoreStorage) ClientByIP(ip net.IP) (Client, error) {
if ip == nil {
addr, _ := netip.AddrFromSlice(ip)
return s.ClientByAddr(addr)
}
func (s *bstoreStorage) ClientByAddr(addr netip.Addr) (Client, error) {
if !addr.IsValid() {
return Client{}, ErrNotExist{Object: "client"}
}
var (
@@ -205,9 +221,9 @@ func (s *bstoreStorage) ClientByIP(ip net.IP) (Client, error) {
clients Clients
network string
)
if ip4 := ip.To4(); ip4 != nil {
if addr.Is4() {
network = "ipv4"
} else if ip6 := ip.To16(); ip6 != nil {
} else {
network = "ipv6"
}
if network == "" {
@@ -216,7 +232,7 @@ func (s *bstoreStorage) ClientByIP(ip net.IP) (Client, error) {
for client, err := range bstore.QueryDB[Client](ctx, s.db).
FilterEqual("Network", network).
FilterFn(func(client Client) bool {
return client.ContainsIP(ip)
return client.ContainsAddr(addr)
}).All() {
if err != nil {
return Client{}, err
@@ -320,6 +336,26 @@ func (s *bstoreStorage) Lists() ([]List, error) {
return lists, nil
}
func (s *bstoreStorage) ListsByGroup(group Group) ([]List, error) {
ctx := context.Background()
ids := make([]int64, 0)
for item, err := range bstore.QueryDB[ListGroup](ctx, s.db).FilterEqual("GroupID", group.ID).All() {
if err != nil {
return nil, err
}
ids = append(ids, item.ListID)
}
var lists []List
for list, err := range bstore.QueryDB[List](ctx, s.db).FilterIDs(ids).All() {
if err != nil {
return nil, err
}
lists = append(lists, list)
}
return lists, nil
}
func (s *bstoreStorage) ListByID(id int64) (List, error) {
ctx := context.Background()
list, err := bstore.QueryDB[List](ctx, s.db).FilterID(id).Get()