Skip to content

Commit

Permalink
Node: fix BITPOS (#2227)
Browse files Browse the repository at this point in the history
Node: fix BITPOS

---------

Signed-off-by: Chloe Yip <[email protected]>
Co-authored-by: Andrew Carbonetto <[email protected]>
Co-authored-by: Yury-Fridlyand <[email protected]>
Co-authored-by: James Xin <[email protected]>
  • Loading branch information
4 people authored Dec 10, 2024
1 parent 6e5fa66 commit 5dddce2
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 177 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
* Node: Replace instances of Redis with Valkey ([#2260](https://github.com/valkey-io/valkey-glide/pull/2260))
* Node: Added binary variant for commands which have `Record` as input or output ([#2207](https://github.com/valkey-io/valkey-glide/pull/2207))
* Node: Renamed `ReturnType` to `GlideReturnType` ([#2241](https://github.com/valkey-io/valkey-glide/pull/2241))
* Node: Fix BITPOS for Valkey8 ([#2227](https://github.com/valkey-io/valkey-glide/pull/2227))
* Node, Python: Rename `stop` to `end` in sorted set queries ([#2214](https://github.com/valkey-io/valkey-glide/pull/2214))
* Node: Added binary variant to sorted set commands - part 1 ([#2190](https://github.com/valkey-io/valkey-glide/pull/2190))
* Node: Added binary variant to HSCAN command ([#2240](https://github.com/valkey-io/valkey-glide/pull/2240))
Expand Down
62 changes: 12 additions & 50 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
BitOffset, // eslint-disable-line @typescript-eslint/no-unused-vars
BitOffsetMultiplier, // eslint-disable-line @typescript-eslint/no-unused-vars
BitOffsetOptions,
BitmapIndexType,
BitwiseOperation,
Boundary,
CoordOrigin, // eslint-disable-line @typescript-eslint/no-unused-vars
Expand Down Expand Up @@ -1874,11 +1873,12 @@ export class BaseClient {
* The offset can also be a negative number indicating an offset starting at the end of the list, with `-1` being
* the last byte of the list, `-2` being the penultimate, and so on.
*
* @see {@link https://valkey.io/commands/bitpos/|valkey.io} for more details.
* @see {@link https://valkey.io/commands/bitpos/|valkey.io} for details.
*
* @param key - The key of the string.
* @param bit - The bit value to match. Must be `0` or `1`.
* @param start - (Optional) The starting offset. If not supplied, the search will start at the beginning of the string.
* @param options - (Optional) The {@link BitOffsetOptions}.
*
* @returns The position of the first occurrence of `bit` in the binary value of the string held at `key`.
* If `start` was provided, the search begins at the offset indicated by `start`.
*
Expand All @@ -1888,61 +1888,23 @@ export class BaseClient {
* const result1 = await client.bitpos("key1", 1);
* console.log(result1); // Output: 1 - The first occurrence of bit value 1 in the string stored at "key1" is at the second position.
*
* const result2 = await client.bitpos("key1", 1, -1);
* const result2 = await client.bitpos("key1", 1, { start: -1 });
* console.log(result2); // Output: 10 - The first occurrence of bit value 1, starting at the last byte in the string stored at "key1", is at the eleventh position.
* ```
*/
public async bitpos(
key: GlideString,
bit: number,
start?: number,
): Promise<number> {
return this.createWritePromise(createBitPos(key, bit, start));
}

/**
* Returns the position of the first bit matching the given `bit` value. The offsets are zero-based indexes, with
* `0` being the first element of the list, `1` being the next, 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.
*
* If you are using Valkey 7.0.0 or above, the optional `indexType` can also be provided to specify whether the
* `start` and `end` offsets specify BIT or BYTE offsets. If `indexType` is not provided, BYTE offsets
* are assumed. If BIT is specified, `start=0` and `end=2` means to look at the first three bits. If BYTE is
* specified, `start=0` and `end=2` means to look at the first three bytes.
*
* @see {@link https://valkey.io/commands/bitpos/|valkey.io} for more details.
*
* @param key - The key of the string.
* @param bit - The bit value to match. Must be `0` or `1`.
* @param start - The starting offset.
* @param end - The ending offset.
* @param indexType - (Optional) The index offset type. This option can only be specified if you are using Valkey
* version 7.0.0 or above. Could be either {@link BitmapIndexType.BYTE} or {@link BitmapIndexType.BIT}. If no
* index type is provided, the indexes will be assumed to be byte indexes.
* @returns The position of the first occurrence from the `start` to the `end` offsets of the `bit` in the binary
* value of the string held at `key`.
*
* @example
* ```typescript
* await client.set("key1", "A12"); // "A12" has binary value 01000001 00110001 00110010
* const result1 = await client.bitposInterval("key1", 1, 1, -1);
* console.log(result1); // Output: 10 - The first occurrence of bit value 1 in the second byte to the last byte of the string stored at "key1" is at the eleventh position.
* const result3 = await client.bitpos("key1", 1, { start: 1, end: -1 });
* console.log(result3); // Output: 10 - The first occurrence of bit value 1 in the second byte to the last byte of the string stored at "key1" is at the eleventh position.
*
* const result2 = await client.bitposInterval("key1", 1, 2, 9, BitmapIndexType.BIT);
* console.log(result2); // Output: 7 - The first occurrence of bit value 1 in the third to tenth bits of the string stored at "key1" is at the eighth position.
* const result4 = await client.bitpos("key1", 1, { start: 2, end: 9, indexType: BitmapIndexType.BIT });
* console.log(result4); // Output: 7 - The first occurrence of bit value 1 in the third to tenth bits of the string stored at "key1" is at the eighth position.
* ```
*/
public async bitposInterval(
public async bitpos(
key: GlideString,
bit: number,
start: number,
end: number,
indexType?: BitmapIndexType,
options?: BitOffsetOptions,
): Promise<number> {
return this.createWritePromise(
createBitPos(key, bit, start, end, indexType),
);
return this.createWritePromise(createBitPos(key, bit, options));
}

/**
Expand Down Expand Up @@ -6577,7 +6539,7 @@ export class BaseClient {
* @see {@link https://valkey.io/commands/bitcount/|valkey.io} for more details.
*
* @param key - The key for the string to count the set bits of.
* @param options - The offset options.
* @param options - The offset options - see {@link BitOffsetOptions}.
* @returns If `options` is provided, returns the number of set bits in the string interval specified by `options`.
* If `options` is not provided, returns the number of set bits in the string stored at `key`.
* Otherwise, if `key` is missing, returns `0` as it is treated as an empty string.
Expand Down
65 changes: 40 additions & 25 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2475,18 +2475,25 @@ export function createFunctionRestore(
}

/**
* Represents offsets specifying a string interval to analyze in the {@link BaseClient.bitcount|bitcount} command. The offsets are
* zero-based indexes, with `0` being the first index of the string, `1` being the next index and so on.
* Represents offsets specifying a string interval to analyze in the {@link BaseClient.bitcount | bitcount} and {@link BaseClient.bitpos | bitpos} commands.
* The offsets are zero-based indexes, with `0` being the first index of the string, `1` being the next index and so on.
* The offsets can also be negative numbers indicating offsets starting at the end of the string, with `-1` being
* the last index of the string, `-2` being the penultimate, and so on.
*
* See https://valkey.io/commands/bitcount/ for more details.
* If you are using Valkey 7.0.0 or above, the optional `indexType` can also be provided to specify whether the
* `start` and `end` offsets specify `BIT` or `BYTE` offsets. If `indexType` is not provided, `BYTE` offsets
* are assumed. If `BIT` is specified, `start=0` and `end=2` means to look at the first three bits. If `BYTE` is
* specified, `start=0` and `end=2` means to look at the first three bytes.
*
* @see {@link https://valkey.io/commands/bitcount/ | bitcount} and {@link https://valkey.io/commands/bitpos/ | bitpos} for more details.
*/
export interface BitOffsetOptions {
/** The starting offset index. */
start: number;
/** The ending offset index. Optional since Valkey version 8.0 and above.
* If not provided, it will default to the end of the string
/**
* The ending offset index. Optional since Valkey version 8.0 and above for the BITCOUNT command.
* If not provided, it will default to the end of the string.
* Could be defined only if `start` is defined.
*/
end?: number;
/**
Expand All @@ -2497,19 +2504,36 @@ export interface BitOffsetOptions {
indexType?: BitmapIndexType;
}

/**
* @internal
*/
function convertBitOptionsToArgs(options?: BitOffsetOptions): GlideString[] {
const args: GlideString[] = [];
if (!options) return args;

args.push(options.start.toString());

if (options.end !== undefined) {
args.push(options.end.toString());

if (options.indexType) args.push(options.indexType);
}

return args;
}

/**
* @internal
*/
export function createBitCount(
key: GlideString,
options?: BitOffsetOptions,
): command_request.Command {
const args = [key];
let args: GlideString[] = [key];

if (options) {
args.push(options.start.toString());
if (options.end !== undefined) args.push(options.end.toString());
if (options.indexType) args.push(options.indexType);
const optionResults: GlideString[] = convertBitOptionsToArgs(options);
args = args.concat(optionResults);
}

return createCommand(RequestType.BitCount, args);
Expand All @@ -2525,6 +2549,7 @@ export function createBitCount(
export enum BitmapIndexType {
/** Specifies that provided indexes are byte indexes. */
BYTE = "BYTE",

/** Specifies that provided indexes are bit indexes. */
BIT = "BIT",
}
Expand All @@ -2535,23 +2560,13 @@ export enum BitmapIndexType {
export function createBitPos(
key: GlideString,
bit: number,
start?: number,
end?: number,
indexType?: BitmapIndexType,
options?: BitOffsetOptions,
): command_request.Command {
const args: GlideString[] = [key, bit.toString()];

if (start !== undefined) {
args.push(start.toString());
}

if (end !== undefined) {
args.push(end.toString());
}

if (indexType) {
args.push(indexType);
}
const args: GlideString[] = [
key,
bit.toString(),
...convertBitOptionsToArgs(options),
];

return createCommand(RequestType.BitPos, args);
}
Expand Down
41 changes: 5 additions & 36 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
BitOffset, // eslint-disable-line @typescript-eslint/no-unused-vars
BitOffsetMultiplier, // eslint-disable-line @typescript-eslint/no-unused-vars
BitOffsetOptions,
BitmapIndexType,
BitwiseOperation,
Boundary,
CoordOrigin, // eslint-disable-line @typescript-eslint/no-unused-vars
Expand Down Expand Up @@ -686,47 +685,17 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
*
* @param key - The key of the string.
* @param bit - The bit value to match. Must be `0` or `1`.
* @param start - (Optional) The starting offset. If not supplied, the search will start at the beginning of the string.
* @param options - (Optional) The {@link BitOffsetOptions}.
*
* Command Response - The position of the first occurrence of `bit` in the binary value of the string held at `key`.
* If `start` was provided, the search begins at the offset indicated by `start`.
*/
public bitpos(key: GlideString, bit: number, start?: number): T {
return this.addAndReturn(createBitPos(key, bit, start));
}

/**
* Returns the position of the first bit matching the given `bit` value. The offsets are zero-based indexes, with
* `0` being the first element of the list, `1` being the next, 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.
*
* If you are using Valkey 7.0.0 or above, the optional `indexType` can also be provided to specify whether the
* `start` and `end` offsets specify BIT or BYTE offsets. If `indexType` is not provided, BYTE offsets
* are assumed. If BIT is specified, `start=0` and `end=2` means to look at the first three bits. If BYTE is
* specified, `start=0` and `end=2` means to look at the first three bytes.
*
* @see {@link https://valkey.io/commands/bitpos/|valkey.io} for details.
*
* @param key - The key of the string.
* @param bit - The bit value to match. Must be `0` or `1`.
* @param start - The starting offset.
* @param end - The ending offset.
* @param indexType - (Optional) The index offset type. This option can only be specified if you are using Valkey
* version 7.0.0 or above. Could be either {@link BitmapIndexType.BYTE} or {@link BitmapIndexType.BIT}. If no
* index type is provided, the indexes will be assumed to be byte indexes.
*
* Command Response - The position of the first occurrence from the `start` to the `end` offsets of the `bit` in the
* binary value of the string held at `key`.
*/
public bitposInterval(
public bitpos(
key: GlideString,
bit: number,
start: number,
end: number,
indexType?: BitmapIndexType,
options?: BitOffsetOptions,
): T {
return this.addAndReturn(createBitPos(key, bit, start, end, indexType));
return this.addAndReturn(createBitPos(key, bit, options));
}

/**
Expand Down Expand Up @@ -3516,7 +3485,7 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
* @see {@link https://valkey.io/commands/bitcount/|valkey.io} for more details.
*
* @param key - The key for the string to count the set bits of.
* @param options - The offset options.
* @param options - The offset options - see {@link BitOffsetOptions}.
*
* Command Response - If `options` is provided, returns the number of set bits in the string interval specified by `options`.
* If `options` is not provided, returns the number of set bits in the string stored at `key`.
Expand Down
Loading

0 comments on commit 5dddce2

Please sign in to comment.