filter theoretical limits.

This commit is contained in:
fiatjaf 2024-11-03 15:54:31 -03:00
parent 1d06176c7e
commit 7fc2f88e79
2 changed files with 55 additions and 0 deletions

View File

@ -170,3 +170,47 @@ func (ef Filter) Clone() Filter {
return clone
}
// GetTheoreticalLimit gets the maximum number of events that a normal filter would ever return, for example, if
// there is a number of "ids" in the filter, the theoretical limit will be that number of ids.
//
// It returns -1 if there are no theoretical limits.
//
// The given .Limit present in the filter is ignored.
func GetTheoreticalLimit(filter Filter) int {
if len(filter.IDs) > 0 {
return len(filter.IDs)
}
if len(filter.Kinds) == 0 {
return -1
}
if len(filter.Authors) > 0 {
allAreReplaceable := true
for _, kind := range filter.Kinds {
if !IsReplaceableKind(kind) {
allAreReplaceable = false
break
}
}
if allAreReplaceable {
return len(filter.Authors) * len(filter.Kinds)
}
if len(filter.Tags["d"]) > 0 {
allAreAddressable := true
for _, kind := range filter.Kinds {
if !IsAddressableKind(kind) {
allAreAddressable = false
break
}
}
if allAreAddressable {
return len(filter.Authors) * len(filter.Kinds) * len(filter.Tags["d"])
}
}
}
return -1
}

View File

@ -6,6 +6,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestFilterUnmarshal(t *testing.T) {
@ -141,3 +142,13 @@ func TestFilterClone(t *testing.T) {
*clone4.Since++
assert.False(t, FilterEqual(flt, clone4), "modifying the clone since should cause it to not be equal anymore")
}
func TestTheoreticalLimit(t *testing.T) {
require.Equal(t, 6, GetTheoreticalLimit(Filter{IDs: []string{"a", "b", "c", "d", "e", "f"}}))
require.Equal(t, 9, GetTheoreticalLimit(Filter{Authors: []string{"a", "b", "c"}, Kinds: []int{3, 0, 10002}}))
require.Equal(t, 4, GetTheoreticalLimit(Filter{Authors: []string{"a", "b", "c", "d"}, Kinds: []int{10050}}))
require.Equal(t, -1, GetTheoreticalLimit(Filter{Authors: []string{"a", "b", "c", "d"}}))
require.Equal(t, -1, GetTheoreticalLimit(Filter{Kinds: []int{3, 0, 10002}}))
require.Equal(t, 24, GetTheoreticalLimit(Filter{Authors: []string{"a", "b", "c", "d", "e", "f"}, Kinds: []int{30023, 30024}, Tags: TagMap{"d": []string{"aaa", "bbb"}}}))
require.Equal(t, -1, GetTheoreticalLimit(Filter{Authors: []string{"a", "b", "c", "d", "e", "f"}, Kinds: []int{30023, 30024}}))
}