@@ -74,65 +74,98 @@ func (bf *BloomFilter) Reset() {
7474}
7575
7676// hash generates multiple hash values for the given key.
77+ // Note: hash.Hash.Write() never returns an error for FNV hash, but we check defensively.
7778func (bf * BloomFilter ) hash (key interface {}) []uint64 { //nolint:gocyclo // Type switch for performance
7879 h := fnv .New64a ()
7980 // Convert key to bytes for hashing - fast paths for common types
8081 switch k := key .(type ) {
8182 case string :
82- _ , _ = h .Write ([]byte (k ))
83+ if _ , err := h .Write ([]byte (k )); err != nil {
84+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
85+ }
8386 case int :
8487 var buf [8 ]byte
8588 binary .BigEndian .PutUint64 (buf [:], uint64 (k )) //nolint:gosec // Safe conversion for hashing
86- _ , _ = h .Write (buf [:])
89+ if _ , err := h .Write (buf [:]); err != nil {
90+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
91+ }
8792 case int8 :
88- _ , _ = h .Write ([]byte {byte (k )})
93+ if _ , err := h .Write ([]byte {byte (k )}); err != nil {
94+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
95+ }
8996 case int16 :
9097 var buf [2 ]byte
9198 binary .BigEndian .PutUint16 (buf [:], uint16 (k )) //nolint:gosec // Safe conversion for hashing
92- _ , _ = h .Write (buf [:])
99+ if _ , err := h .Write (buf [:]); err != nil {
100+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
101+ }
93102 case int32 :
94103 var buf [4 ]byte
95104 binary .BigEndian .PutUint32 (buf [:], uint32 (k )) //nolint:gosec // Safe conversion for hashing
96- _ , _ = h .Write (buf [:])
105+ if _ , err := h .Write (buf [:]); err != nil {
106+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
107+ }
97108 case int64 :
98109 var buf [8 ]byte
99110 binary .BigEndian .PutUint64 (buf [:], uint64 (k )) //nolint:gosec // Safe conversion for hashing
100- _ , _ = h .Write (buf [:])
111+ if _ , err := h .Write (buf [:]); err != nil {
112+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
113+ }
101114 case uint :
102115 var buf [8 ]byte
103116 binary .BigEndian .PutUint64 (buf [:], uint64 (k ))
104- _ , _ = h .Write (buf [:])
117+ if _ , err := h .Write (buf [:]); err != nil {
118+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
119+ }
105120 case uint8 :
106- _ , _ = h .Write ([]byte {k })
121+ if _ , err := h .Write ([]byte {k }); err != nil {
122+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
123+ }
107124 case uint16 :
108125 var buf [2 ]byte
109126 binary .BigEndian .PutUint16 (buf [:], k )
110- _ , _ = h .Write (buf [:])
127+ if _ , err := h .Write (buf [:]); err != nil {
128+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
129+ }
111130 case uint32 :
112131 var buf [4 ]byte
113132 binary .BigEndian .PutUint32 (buf [:], k )
114- _ , _ = h .Write (buf [:])
133+ if _ , err := h .Write (buf [:]); err != nil {
134+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
135+ }
115136 case uint64 :
116137 var buf [8 ]byte
117138 binary .BigEndian .PutUint64 (buf [:], k )
118- _ , _ = h .Write (buf [:])
139+ if _ , err := h .Write (buf [:]); err != nil {
140+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
141+ }
119142 case float32 :
120143 var buf [4 ]byte
121144 binary .BigEndian .PutUint32 (buf [:], math .Float32bits (k ))
122- _ , _ = h .Write (buf [:])
145+ if _ , err := h .Write (buf [:]); err != nil {
146+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
147+ }
123148 case float64 :
124149 var buf [8 ]byte
125150 binary .BigEndian .PutUint64 (buf [:], math .Float64bits (k ))
126- _ , _ = h .Write (buf [:])
151+ if _ , err := h .Write (buf [:]); err != nil {
152+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
153+ }
127154 case bool :
128155 if k {
129- _ , _ = h .Write ([]byte {1 })
156+ if _ , err := h .Write ([]byte {1 }); err != nil {
157+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
158+ }
130159 } else {
131- _ , _ = h .Write ([]byte {0 })
160+ if _ , err := h .Write ([]byte {0 }); err != nil {
161+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
162+ }
132163 }
133164 default :
134165 // For other types (structs, arrays, etc), use fmt.Fprintf for generic conversion
135- _ , _ = fmt .Fprintf (h , "%v" , key )
166+ if _ , err := fmt .Fprintf (h , "%v" , key ); err != nil {
167+ panic (fmt .Sprintf ("unexpected hash.Write error: %v" , err ))
168+ }
136169 }
137170 hash1 := h .Sum64 ()
138171 // Generate additional hashes using double hashing
@@ -685,6 +718,7 @@ func NewWithDeduplication[T comparable](size int, timeout time.Duration, fn func
685718 triggerCh : make (chan struct {}),
686719 background : background ,
687720 usePool : false ,
721+ done : make (chan struct {}),
688722 },
689723 deduplicationWindow : deduplicationWindow ,
690724 // Create an optimized time-partitioned map with bloom filter
@@ -710,6 +744,7 @@ func NewWithDeduplicationAndPool[T comparable](size int, timeout time.Duration,
710744 triggerCh : make (chan struct {}),
711745 background : background ,
712746 usePool : true ,
747+ done : make (chan struct {}),
713748 pool : & sync.Pool {
714749 New : func () interface {} {
715750 slice := make ([]* T , 0 , size )
@@ -727,8 +762,19 @@ func NewWithDeduplicationAndPool[T comparable](size int, timeout time.Duration,
727762 return b
728763}
729764
730- // Close properly shuts down the deduplication map resources.
765+ // Close properly shuts down the batcher and deduplication map resources.
766+ //
767+ // This method performs a graceful shutdown by:
768+ // 1. Stopping the background worker goroutine via the parent Batcher.Close()
769+ // 2. Processing any remaining items in the queue
770+ // 3. Closing the deduplication map and stopping its cleanup ticker
771+ //
772+ // It is safe to call Close() multiple times (subsequent calls have no effect).
773+ //
774+ // IMPORTANT: Do not call Put() after Close() has been called, as this will
775+ // result in a panic due to sending on a closed channel.
731776func (b * BatcherWithDedup [T ]) Close () {
777+ b .Batcher .Close ()
732778 b .deduplicationMap .Close ()
733779}
734780
0 commit comments