Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go: Implement GetBit, SetBit, BitCount and Wait commands #2918

Merged
merged 22 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b86f764
Added bitmap commands,wait commands
niharikabhavaraju Jan 6, 2025
b505e61
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 6, 2025
962455f
Fixed Lint error
niharikabhavaraju Jan 6, 2025
cfab63c
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 13, 2025
578ce72
Fix merge conflicts
niharikabhavaraju Jan 13, 2025
d3c888c
Fixed code review
niharikabhavaraju Jan 13, 2025
42bebc8
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 15, 2025
41d9231
Fixed code review comments
niharikabhavaraju Jan 16, 2025
16c5ab4
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 16, 2025
92c5654
Fixed tests version
niharikabhavaraju Jan 16, 2025
7b4a40b
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 16, 2025
2beb116
Fixed lint error
niharikabhavaraju Jan 16, 2025
ba371a5
Merge branch 'niharika-bitcommands' of github.com:niharikabhavaraju/v…
niharikabhavaraju Jan 16, 2025
1a68857
Minor error fix
niharikabhavaraju Jan 16, 2025
b471e7f
Fixed code review comments
niharikabhavaraju Jan 17, 2025
e4d5590
Merge branch 'main' of github.com:niharikabhavaraju/valkey-glide into…
niharikabhavaraju Jan 17, 2025
0b8635b
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 20, 2025
e9e82b3
Fixed review comments
niharikabhavaraju Jan 20, 2025
5764e7e
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 20, 2025
7fe7e6b
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 21, 2025
d93707c
Fixed minor code review changes
niharikabhavaraju Jan 21, 2025
b817aa8
Merge branch 'main' into niharika-bitcommands
niharikabhavaraju Jan 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions go/api/base_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type BaseClient interface {
ConnectionManagementCommands
HyperLogLogCommands
GenericBaseCommands
BitmapCommands
// Close terminates the client by closing all associated resources.
Close()
}
Expand Down Expand Up @@ -3162,3 +3163,150 @@ func (client *baseClient) XAck(key string, group string, ids []string) (int64, e
}
return handleIntResponse(result)
}

// Sets or clears the bit at offset in the string value stored at key.
// The offset is a zero-based index, with `0` being the first element of
// the list, `1` being the next element, and so on. The offset must be
// less than `2^32` and greater than or equal to `0` If a key is
// non-existent then the bit at offset is set to value and the preceding
// bits are set to `0`.
//
// Parameters:
//
// key - The key of the string.
// offset - The index of the bit to be set.
// value - The bit value to set at offset The value must be `0` or `1`.
//
// Return value:
//
// The bit value that was previously stored at offset.
//
// Example:
//
// result, err := client.SetBit("key", 1, 1)
// result: 1
//
// [valkey.io]: https://valkey.io/commands/setbit/
func (client *baseClient) SetBit(key string, offset int64, value int64) (int64, error) {
result, err := client.executeCommand(C.SetBit, []string{key, utils.IntToString(offset), utils.IntToString(value)})
if err != nil {
return defaultIntResponse, err
}
return handleIntResponse(result)
}

// Returns the bit value at offset in the string value stored at key.
//
// offset should be greater than or equal to zero.
//
// Parameters:
//
// key - The key of the string.
// offset - The index of the bit to return.
//
// Return value:
// The bit at offset of the string. Returns zero if the key is empty or if the positive
// offset exceeds the length of the string.
//
// Example:
//
// result, err := client.GetBit("key1", 1, 1)
// result: 1
//
// [valkey.io]: https://valkey.io/commands/getbit/
func (client *baseClient) GetBit(key string, offset int64) (int64, error) {
result, err := client.executeCommand(C.GetBit, []string{key, utils.IntToString(offset)})
if err != nil {
return defaultIntResponse, err
}
return handleIntResponse(result)
}

// Wait blocks the current client until all the previous write commands are successfully
// transferred and acknowledged by at least the specified number of replicas or if the timeout is reached,
// whichever is earlier
//
// Parameters:
//
// numberOfReplicas - The number of replicas to reach.
// timeout - The timeout value specified in milliseconds. A value of `0` will
// block indefinitely.
//
// Return value:
// The number of replicas reached by all the writes performed in the context of the current connection.
//
// Example:
//
// result, err := client.Wait(1, 1000)
// if err != nil {
// // handle error
// }
// fmt.Println(result.Value()) // Output: 1 // if cluster has 2 replicasets
//
// [valkey.io]: https://valkey.io/commands/wait/
func (client *baseClient) Wait(numberOfReplicas int64, timeout int64) (int64, error) {
result, err := client.executeCommand(C.Wait, []string{utils.IntToString(numberOfReplicas), utils.IntToString(timeout)})
if err != nil {
return defaultIntResponse, err
}
return handleIntResponse(result)
}

// Counts the number of set bits (population counting) in a string stored at key.
//
// Parameters:
//
// key - The key for the string to count the set bits of.
//
// Return value:
// The number of set bits in the string. Returns zero if the key is missing as it is
// treated as an empty string.
//
// Example:
//
// result, err := client.BitCount("mykey")
// result: 26
//
// [valkey.io]: https://valkey.io/commands/bitcount/
func (client *baseClient) BitCount(key string) (int64, error) {
result, err := client.executeCommand(C.BitCount, []string{key})
if err != nil {
return defaultIntResponse, err
}
return handleIntResponse(result)
}

// Counts the number of set bits (population counting) in a string stored at key. The
// offsets start and end are zero-based indexes, with `0` being the first element of the
// list, `1` being the next element and so on. These offsets can also be negative numbers
// indicating offsets starting at the end of the list, with `-1` being the last element
// of the list, `-2` being the penultimate, and so on.
//
// Parameters:
//
// key - The key for the string to count the set bits of.
// options - The offset options - see [options.BitOffsetOptions].
//
// Return value:
// The number of set bits in the string interval specified by start, end, and options.
// Returns zero if the key is missing as it is treated as an empty string.
//
// Example:
//
// opts := NewBitCountOptionsBuilder().SetStart(1).SetEnd(1).SetBitmapIndexType(options.BYTE)
// result, err := client.BitCount("mykey",options)
// result: 6
//
// [valkey.io]: https://valkey.io/commands/bitcount/
func (client *baseClient) BitCountWithOptions(key string, opts *options.BitCountOptions) (int64, error) {
optionArgs, err := opts.ToArgs()
if err != nil {
return defaultIntResponse, err
}
commandArgs := append([]string{key}, optionArgs...)
result, err := client.executeCommand(C.BitCount, commandArgs)
if err != nil {
return defaultIntResponse, err
}
return handleIntResponse(result)
}
20 changes: 20 additions & 0 deletions go/api/bitmap_commands.go
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0

package api

import "github.com/valkey-io/valkey-glide/go/glide/api/options"

// Supports commands and transactions for the "Bitmap" group of commands for standalone and cluster clients.
//
// See [valkey.io] for details.
//
// [valkey.io]: https://valkey.io/commands/#bitmap
type BitmapCommands interface {
SetBit(key string, offset int64, value int64) (int64, error)

GetBit(key string, offset int64) (int64, error)

BitCount(key string) (int64, error)

BitCountWithOptions(key string, options *options.BitCountOptions) (int64, error)
}
2 changes: 2 additions & 0 deletions go/api/generic_base_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -703,4 +703,6 @@ type GenericBaseCommands interface {
//
// [valkey.io]: https://valkey.io/commands/sort/
SortReadOnlyWithOptions(key string, sortOptions *options.SortOptions) ([]Result[string], error)

Wait(numberOfReplicas int64, timeout int64) (int64, error)
}
63 changes: 63 additions & 0 deletions go/api/options/bitcount_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0

package options

import (
"github.com/valkey-io/valkey-glide/go/glide/utils"
)

type BitmapIndexType string

const (
BYTE BitmapIndexType = "BYTE"
BIT BitmapIndexType = "BIT"
)

// Optional arguments to `BitCount` in [BitMapCommands]
type BitCountOptions struct {
start *int64
end *int64
bitMapIndexType BitmapIndexType
}

func NewBitCountOptionsBuilder() *BitCountOptions {
return &BitCountOptions{}
}

// SetStart defines start byte to calculate bitcount in bitcount command.
func (options *BitCountOptions) SetStart(start int64) *BitCountOptions {
options.start = &start
return options
}

// SetEnd defines start byte to calculate bitcount in bitcount command.
func (options *BitCountOptions) SetEnd(end int64) *BitCountOptions {
options.end = &end
return options
}

// SetBitmapIndexType to specify start and end are in BYTE or BIT
func (options *BitCountOptions) SetBitmapIndexType(bitMapIndexType BitmapIndexType) *BitCountOptions {
options.bitMapIndexType = bitMapIndexType
return options
}

// ToArgs converts the options to a list of arguments.
func (opts *BitCountOptions) ToArgs() ([]string, error) {
args := []string{}
var err error

if opts.start != nil {
args = append(args, utils.IntToString(*opts.start))
if opts.end != nil {
args = append(args, utils.IntToString(*opts.end))
if opts.bitMapIndexType != "" {
if opts.bitMapIndexType == BIT || opts.bitMapIndexType == BYTE {
args = append(args, string(opts.bitMapIndexType))
}
}
}
}

return args, err
}
Loading
Loading