...

Source file src/github.com/redis/go-redis/v9/bitmap_commands.go

Documentation: github.com/redis/go-redis/v9

     1  package redis
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  )
     7  
     8  type BitMapCmdable interface {
     9  	GetBit(ctx context.Context, key string, offset int64) *IntCmd
    10  	SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd
    11  	BitCount(ctx context.Context, key string, bitCount *BitCount) *IntCmd
    12  	BitOpAnd(ctx context.Context, destKey string, keys ...string) *IntCmd
    13  	BitOpOr(ctx context.Context, destKey string, keys ...string) *IntCmd
    14  	BitOpXor(ctx context.Context, destKey string, keys ...string) *IntCmd
    15  	BitOpDiff(ctx context.Context, destKey string, keys ...string) *IntCmd
    16  	BitOpDiff1(ctx context.Context, destKey string, keys ...string) *IntCmd
    17  	BitOpAndOr(ctx context.Context, destKey string, keys ...string) *IntCmd
    18  	BitOpOne(ctx context.Context, destKey string, keys ...string) *IntCmd
    19  	BitOpNot(ctx context.Context, destKey string, key string) *IntCmd
    20  	BitPos(ctx context.Context, key string, bit int64, pos ...int64) *IntCmd
    21  	BitPosSpan(ctx context.Context, key string, bit int8, start, end int64, span string) *IntCmd
    22  	BitField(ctx context.Context, key string, values ...interface{}) *IntSliceCmd
    23  	BitFieldRO(ctx context.Context, key string, values ...interface{}) *IntSliceCmd
    24  }
    25  
    26  func (c cmdable) GetBit(ctx context.Context, key string, offset int64) *IntCmd {
    27  	cmd := NewIntCmd(ctx, "getbit", key, offset)
    28  	_ = c(ctx, cmd)
    29  	return cmd
    30  }
    31  
    32  func (c cmdable) SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd {
    33  	cmd := NewIntCmd(
    34  		ctx,
    35  		"setbit",
    36  		key,
    37  		offset,
    38  		value,
    39  	)
    40  	_ = c(ctx, cmd)
    41  	return cmd
    42  }
    43  
    44  type BitCount struct {
    45  	Start, End int64
    46  	Unit       string // BYTE(default) | BIT
    47  }
    48  
    49  const BitCountIndexByte string = "BYTE"
    50  const BitCountIndexBit string = "BIT"
    51  
    52  func (c cmdable) BitCount(ctx context.Context, key string, bitCount *BitCount) *IntCmd {
    53  	args := make([]any, 2, 5)
    54  	args[0] = "bitcount"
    55  	args[1] = key
    56  	if bitCount != nil {
    57  		args = append(args, bitCount.Start, bitCount.End)
    58  		if bitCount.Unit != "" {
    59  			if bitCount.Unit != BitCountIndexByte && bitCount.Unit != BitCountIndexBit {
    60  				cmd := NewIntCmd(ctx)
    61  				cmd.SetErr(errors.New("redis: invalid bitcount index"))
    62  				return cmd
    63  			}
    64  			args = append(args, bitCount.Unit)
    65  		}
    66  	}
    67  	cmd := NewIntCmd(ctx, args...)
    68  	_ = c(ctx, cmd)
    69  	return cmd
    70  }
    71  
    72  func (c cmdable) bitOp(ctx context.Context, op, destKey string, keys ...string) *IntCmd {
    73  	args := make([]interface{}, 3+len(keys))
    74  	args[0] = "bitop"
    75  	args[1] = op
    76  	args[2] = destKey
    77  	for i, key := range keys {
    78  		args[3+i] = key
    79  	}
    80  	cmd := NewIntCmd(ctx, args...)
    81  	_ = c(ctx, cmd)
    82  	return cmd
    83  }
    84  
    85  // BitOpAnd creates a new bitmap in which users are members of all given bitmaps
    86  func (c cmdable) BitOpAnd(ctx context.Context, destKey string, keys ...string) *IntCmd {
    87  	return c.bitOp(ctx, "and", destKey, keys...)
    88  }
    89  
    90  // BitOpOr creates a new bitmap in which users are member of at least one given bitmap
    91  func (c cmdable) BitOpOr(ctx context.Context, destKey string, keys ...string) *IntCmd {
    92  	return c.bitOp(ctx, "or", destKey, keys...)
    93  }
    94  
    95  // BitOpXor creates a new bitmap in which users are the result of XORing all given bitmaps
    96  func (c cmdable) BitOpXor(ctx context.Context, destKey string, keys ...string) *IntCmd {
    97  	return c.bitOp(ctx, "xor", destKey, keys...)
    98  }
    99  
   100  // BitOpNot creates a new bitmap in which users are not members of a given bitmap
   101  func (c cmdable) BitOpNot(ctx context.Context, destKey string, key string) *IntCmd {
   102  	return c.bitOp(ctx, "not", destKey, key)
   103  }
   104  
   105  // BitOpDiff creates a new bitmap in which users are members of bitmap X but not of any of bitmaps Y1, Y2, …
   106  // Introduced with Redis 8.2
   107  func (c cmdable) BitOpDiff(ctx context.Context, destKey string, keys ...string) *IntCmd {
   108  	return c.bitOp(ctx, "diff", destKey, keys...)
   109  }
   110  
   111  // BitOpDiff1 creates a new bitmap in which users are members of one or more of bitmaps Y1, Y2, … but not members of bitmap X
   112  // Introduced with Redis 8.2
   113  func (c cmdable) BitOpDiff1(ctx context.Context, destKey string, keys ...string) *IntCmd {
   114  	return c.bitOp(ctx, "diff1", destKey, keys...)
   115  }
   116  
   117  // BitOpAndOr creates a new bitmap in which users are members of bitmap X and also members of one or more of bitmaps Y1, Y2, …
   118  // Introduced with Redis 8.2
   119  func (c cmdable) BitOpAndOr(ctx context.Context, destKey string, keys ...string) *IntCmd {
   120  	return c.bitOp(ctx, "andor", destKey, keys...)
   121  }
   122  
   123  // BitOpOne creates a new bitmap in which users are members of exactly one of the given bitmaps
   124  // Introduced with Redis 8.2
   125  func (c cmdable) BitOpOne(ctx context.Context, destKey string, keys ...string) *IntCmd {
   126  	return c.bitOp(ctx, "one", destKey, keys...)
   127  }
   128  
   129  // BitPos is an API before Redis version 7.0, cmd: bitpos key bit start end
   130  // if you need the `byte | bit` parameter, please use `BitPosSpan`.
   131  func (c cmdable) BitPos(ctx context.Context, key string, bit int64, pos ...int64) *IntCmd {
   132  	args := make([]interface{}, 3+len(pos))
   133  	args[0] = "bitpos"
   134  	args[1] = key
   135  	args[2] = bit
   136  	switch len(pos) {
   137  	case 0:
   138  	case 1:
   139  		args[3] = pos[0]
   140  	case 2:
   141  		args[3] = pos[0]
   142  		args[4] = pos[1]
   143  	default:
   144  		panic("too many arguments")
   145  	}
   146  	cmd := NewIntCmd(ctx, args...)
   147  	_ = c(ctx, cmd)
   148  	return cmd
   149  }
   150  
   151  // BitPosSpan supports the `byte | bit` parameters in redis version 7.0,
   152  // the bitpos command defaults to using byte type for the `start-end` range,
   153  // which means it counts in bytes from start to end. you can set the value
   154  // of "span" to determine the type of `start-end`.
   155  // span = "bit", cmd: bitpos key bit start end bit
   156  // span = "byte", cmd: bitpos key bit start end byte
   157  func (c cmdable) BitPosSpan(ctx context.Context, key string, bit int8, start, end int64, span string) *IntCmd {
   158  	cmd := NewIntCmd(ctx, "bitpos", key, bit, start, end, span)
   159  	_ = c(ctx, cmd)
   160  	return cmd
   161  }
   162  
   163  // BitField accepts multiple values:
   164  //   - BitField("set", "i1", "offset1", "value1","cmd2", "type2", "offset2", "value2")
   165  //   - BitField([]string{"cmd1", "type1", "offset1", "value1","cmd2", "type2", "offset2", "value2"})
   166  //   - BitField([]interface{}{"cmd1", "type1", "offset1", "value1","cmd2", "type2", "offset2", "value2"})
   167  func (c cmdable) BitField(ctx context.Context, key string, values ...interface{}) *IntSliceCmd {
   168  	args := make([]interface{}, 2, 2+len(values))
   169  	args[0] = "bitfield"
   170  	args[1] = key
   171  	args = appendArgs(args, values)
   172  	cmd := NewIntSliceCmd(ctx, args...)
   173  	_ = c(ctx, cmd)
   174  	return cmd
   175  }
   176  
   177  // BitFieldRO - Read-only variant of the BITFIELD command.
   178  // It is like the original BITFIELD but only accepts GET subcommand and can safely be used in read-only replicas.
   179  // - BitFieldRO(ctx, key, "<Encoding0>", "<Offset0>", "<Encoding1>","<Offset1>")
   180  func (c cmdable) BitFieldRO(ctx context.Context, key string, values ...interface{}) *IntSliceCmd {
   181  	args := make([]interface{}, 2, 2+len(values))
   182  	args[0] = "BITFIELD_RO"
   183  	args[1] = key
   184  	if len(values)%2 != 0 {
   185  		panic("BitFieldRO: invalid number of arguments, must be even")
   186  	}
   187  	for i := 0; i < len(values); i += 2 {
   188  		args = append(args, "GET", values[i], values[i+1])
   189  	}
   190  	cmd := NewIntSliceCmd(ctx, args...)
   191  	_ = c(ctx, cmd)
   192  	return cmd
   193  }
   194  

View as plain text