@@ -3,9 +3,10 @@ package redis_bloom_go
3
3
import (
4
4
"errors"
5
5
"fmt"
6
- "github.com/gomodule/redigo/redis"
7
6
"strconv"
8
7
"strings"
8
+
9
+ "github.com/gomodule/redigo/redis"
9
10
)
10
11
11
12
// TODO: refactor this hard limit and revise client locking
@@ -24,8 +25,8 @@ type TDigestInfo struct {
24
25
capacity int64
25
26
mergedNodes int64
26
27
unmergedNodes int64
27
- mergedWeight float64
28
- unmergedWeight float64
28
+ mergedWeight int64
29
+ unmergedWeight int64
29
30
totalCompressions int64
30
31
}
31
32
@@ -50,12 +51,12 @@ func (info *TDigestInfo) UnmergedNodes() int64 {
50
51
}
51
52
52
53
// MergedWeight - returns the merged weight of TDigestInfo instance
53
- func (info * TDigestInfo ) MergedWeight () float64 {
54
+ func (info * TDigestInfo ) MergedWeight () int64 {
54
55
return info .mergedWeight
55
56
}
56
57
57
58
// UnmergedWeight - returns the unmerged weight of TDigestInfo instance
58
- func (info * TDigestInfo ) UnmergedWeight () float64 {
59
+ func (info * TDigestInfo ) UnmergedWeight () int64 {
59
60
return info .unmergedWeight
60
61
}
61
62
@@ -499,7 +500,7 @@ func (client *Client) CfInfo(key string) (map[string]int64, error) {
499
500
func (client * Client ) TdCreate (key string , compression int64 ) (string , error ) {
500
501
conn := client .Pool .Get ()
501
502
defer conn .Close ()
502
- return redis .String (conn .Do ("TDIGEST.CREATE" , key , compression ))
503
+ return redis .String (conn .Do ("TDIGEST.CREATE" , key , "COMPRESSION" , compression ))
503
504
}
504
505
505
506
// TdReset - Reset the sketch to zero - empty out the sketch and re-initialize it
@@ -521,11 +522,48 @@ func (client *Client) TdAdd(key string, samples map[float64]float64) (string, er
521
522
return redis .String (reply , err )
522
523
}
523
524
524
- // TdMerge - Merges all of the values from 'from' to 'this' sketch
525
- func (client * Client ) TdMerge (toKey string , fromKey string ) (string , error ) {
525
+ // tdMerge - The internal representation of TdMerge. All underlying functions call this one,
526
+ // returning its results. It allows us to maintain interfaces.
527
+ // see https://redis.io/commands/tdigest.merge/
528
+ //
529
+ // The default values for compression is 100
530
+ func (client * Client ) tdMerge (toKey string , compression int64 , override bool , numKeys int64 , fromKey ... string ) (string , error ) {
531
+ if numKeys < 1 {
532
+ return "" , errors .New ("a minimum of one key must be merged" )
533
+ }
534
+
526
535
conn := client .Pool .Get ()
527
536
defer conn .Close ()
528
- return redis .String (conn .Do ("TDIGEST.MERGE" , toKey , fromKey ))
537
+ overidable := ""
538
+ if override {
539
+ overidable = "1"
540
+ }
541
+ return redis .String (conn .Do ("TDIGEST.MERGE" , toKey ,
542
+ strconv .FormatInt (numKeys , 10 ),
543
+ strings .Join (fromKey , " " ),
544
+ "COMPRESSION" , compression ,
545
+ overidable ))
546
+ }
547
+
548
+ // TdMerge - Merges all of the values from 'from' to 'this' sketch
549
+ func (client * Client ) TdMerge (toKey string , numKeys int64 , fromKey ... string ) (string , error ) {
550
+ return client .tdMerge (toKey , 100 , false , numKeys , fromKey ... )
551
+ }
552
+
553
+ // TdMergeWithCompression - Merges all of the values from 'from' to 'this' sketch with specified compression
554
+ func (client * Client ) TdMergeWithCompression (toKey string , compression int64 , numKeys int64 , fromKey ... string ) (string , error ) {
555
+ return client .tdMerge (toKey , compression , false , numKeys , fromKey ... )
556
+ }
557
+
558
+ // TdMergeWithOverride - Merges all of the values from 'from' to 'this' sketch overriding the destination key if it exists
559
+ func (client * Client ) TdMergeWithOverride (toKey string , override bool , numKeys int64 , fromKey ... string ) (string , error ) {
560
+ return client .tdMerge (toKey , 100 , true , numKeys , fromKey ... )
561
+ }
562
+
563
+ // TdMergeWithCompressionAndOverride - Merges all of the values from 'from' to 'this' sketch with specified compression
564
+ // and overriding the destination key if it exists
565
+ func (client * Client ) TdMergeWithCompressionAndOverride (toKey string , compression int64 , numKeys int64 , fromKey ... string ) (string , error ) {
566
+ return client .tdMerge (toKey , compression , true , numKeys , fromKey ... )
529
567
}
530
568
531
569
// TdMin - Get minimum value from the sketch. Will return DBL_MAX if the sketch is empty
@@ -544,17 +582,22 @@ func (client *Client) TdMax(key string) (float64, error) {
544
582
545
583
// TdQuantile - Returns an estimate of the cutoff such that a specified fraction of the data added
546
584
// to this TDigest would be less than or equal to the cutoff
547
- func (client * Client ) TdQuantile (key string , quantile float64 ) (float64 , error ) {
585
+ func (client * Client ) TdQuantile (key string , quantile float64 ) ([] float64 , error ) {
548
586
conn := client .Pool .Get ()
549
587
defer conn .Close ()
550
- return redis .Float64 (conn .Do ("TDIGEST.QUANTILE" , key , quantile ))
588
+ return redis .Float64s (conn .Do ("TDIGEST.QUANTILE" , key , quantile ))
551
589
}
552
590
553
- // TdCdf - Returns the fraction of all points added which are <= value
554
- func (client * Client ) TdCdf (key string , value float64 ) (float64 , error ) {
591
+ // TdCdf - Returns the list of fractions of all points added which are <= values
592
+ func (client * Client ) TdCdf (key string , values ... float64 ) ([] float64 , error ) {
555
593
conn := client .Pool .Get ()
556
594
defer conn .Close ()
557
- return redis .Float64 (conn .Do ("TDIGEST.CDF" , key , value ))
595
+
596
+ args := make ([]string , len (values ))
597
+ for idx , obj := range values {
598
+ args [idx ] = strconv .FormatFloat (obj , 'f' , - 1 , 64 )
599
+ }
600
+ return redis .Float64s (conn .Do ("TDIGEST.CDF" , key , strings .Join (args , " " )))
558
601
}
559
602
560
603
// TdInfo - Returns compression, capacity, total merged and unmerged nodes, the total
@@ -590,6 +633,9 @@ func ParseTDigestInfo(result interface{}, err error) (info TDigestInfo, outErr e
590
633
var key string
591
634
for i := 0 ; i < len (values ); i += 2 {
592
635
key , outErr = redis .String (values [i ], nil )
636
+ if outErr != nil {
637
+ return TDigestInfo {}, outErr
638
+ }
593
639
switch key {
594
640
case "Compression" :
595
641
info .compression , outErr = redis .Int64 (values [i + 1 ], nil )
@@ -600,9 +646,9 @@ func ParseTDigestInfo(result interface{}, err error) (info TDigestInfo, outErr e
600
646
case "Unmerged nodes" :
601
647
info .unmergedNodes , outErr = redis .Int64 (values [i + 1 ], nil )
602
648
case "Merged weight" :
603
- info .mergedWeight , outErr = redis .Float64 (values [i + 1 ], nil )
649
+ info .mergedWeight , outErr = redis .Int64 (values [i + 1 ], nil )
604
650
case "Unmerged weight" :
605
- info .unmergedWeight , outErr = redis .Float64 (values [i + 1 ], nil )
651
+ info .unmergedWeight , outErr = redis .Int64 (values [i + 1 ], nil )
606
652
case "Total compressions" :
607
653
info .totalCompressions , outErr = redis .Int64 (values [i + 1 ], nil )
608
654
}
0 commit comments