From 7fc2f88e796f75edacde0c1c75a6a4073e3cc76c Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Sun, 3 Nov 2024 15:54:31 -0300 Subject: [PATCH] filter theoretical limits. --- filter.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ filter_test.go | 11 +++++++++++ 2 files changed, 55 insertions(+) diff --git a/filter.go b/filter.go index e28ad5a..68e03e1 100644 --- a/filter.go +++ b/filter.go @@ -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 +} diff --git a/filter_test.go b/filter_test.go index 0ee21e6..c9f6d56 100644 --- a/filter_test.go +++ b/filter_test.go @@ -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}})) +}