pool: support CountMany() using hyperloglog.

This commit is contained in:
fiatjaf
2024-11-16 16:59:24 -03:00
parent 99e45035d5
commit 0d40b40c9c
7 changed files with 72 additions and 19 deletions

View File

@ -2,6 +2,7 @@ package nostr
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"strconv"
@ -142,7 +143,8 @@ func (v ReqEnvelope) MarshalJSON() ([]byte, error) {
type CountEnvelope struct {
SubscriptionID string
Filters
Count *int64
Count *int64
HyperLogLog []byte
}
func (_ CountEnvelope) Label() string { return "COUNT" }
@ -161,9 +163,11 @@ func (v *CountEnvelope) UnmarshalJSON(data []byte) error {
var countResult struct {
Count *int64 `json:"count"`
HLL string `json:"hll"`
}
if err := json.Unmarshal([]byte(arr[2].Raw), &countResult); err == nil && countResult.Count != nil {
v.Count = countResult.Count
v.HyperLogLog, _ = hex.DecodeString(countResult.HLL)
return nil
}
@ -189,6 +193,13 @@ func (v CountEnvelope) MarshalJSON() ([]byte, error) {
if v.Count != nil {
w.RawString(`,{"count":`)
w.RawString(strconv.FormatInt(*v.Count, 10))
if v.HyperLogLog != nil {
w.RawString(`,"hll":"`)
hllHex := make([]byte, 0, 512)
hex.Encode(hllHex, v.HyperLogLog)
w.Buffer.AppendBytes(hllHex)
w.RawString(`"`)
}
w.RawString(`}`)
} else {
for _, filter := range v.Filters {