You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-10 11:43:01 +03:00
* CSC POC ontop of Parser * add csc file that weren't merged after patch * address review comments * nits to try and fix github * last change from review * Update client-side cache and improve documentation * Add client side caching RESP3 validation * Add documentation for RESP and unstableResp3 options * Add comprehensive cache statistics The `CacheStats` class provides detailed metrics like hit/miss counts, load success/failure counts, total load time, and eviction counts. It also offers derived metrics such as hit/miss rates, load failure rate, and average load penalty. The design is inspired by Caffeine. `BasicClientSideCache` now uses a `StatsCounter` to accumulate these statistics, exposed via a new `stats()` method. The previous `cacheHits()` and `cacheMisses()` methods have been removed. A `recordStats` option (default: true) in `ClientSideCacheConfig` allows disabling statistics collection. --------- Co-authored-by: Shaya Potter <shaya@redislabs.com>
95 lines
2.1 KiB
TypeScript
95 lines
2.1 KiB
TypeScript
import { CommandParser } from '../client/parser';
|
|
import { RedisArgument, ArrayReply, BlobStringReply, Command } from '../RESP/types';
|
|
|
|
export type GeoUnits = 'm' | 'km' | 'mi' | 'ft';
|
|
|
|
export interface GeoCoordinates {
|
|
longitude: RedisArgument | number;
|
|
latitude: RedisArgument | number;
|
|
}
|
|
|
|
export type GeoSearchFrom = RedisArgument | GeoCoordinates;
|
|
|
|
export interface GeoSearchByRadius {
|
|
radius: number;
|
|
unit: GeoUnits;
|
|
}
|
|
|
|
export interface GeoSearchByBox {
|
|
width: number;
|
|
height: number;
|
|
unit: GeoUnits;
|
|
}
|
|
|
|
export type GeoSearchBy = GeoSearchByRadius | GeoSearchByBox;
|
|
|
|
export function parseGeoSearchArguments(
|
|
parser: CommandParser,
|
|
key: RedisArgument,
|
|
from: GeoSearchFrom,
|
|
by: GeoSearchBy,
|
|
options?: GeoSearchOptions,
|
|
) {
|
|
parser.pushKey(key);
|
|
|
|
if (typeof from === 'string' || from instanceof Buffer) {
|
|
parser.push('FROMMEMBER', from);
|
|
} else {
|
|
parser.push('FROMLONLAT', from.longitude.toString(), from.latitude.toString());
|
|
}
|
|
|
|
if ('radius' in by) {
|
|
parser.push('BYRADIUS', by.radius.toString(), by.unit);
|
|
} else {
|
|
parser.push('BYBOX', by.width.toString(), by.height.toString(), by.unit);
|
|
}
|
|
|
|
parseGeoSearchOptions(parser, options);
|
|
}
|
|
|
|
export type GeoCountArgument = number | {
|
|
value: number;
|
|
ANY?: boolean;
|
|
};
|
|
|
|
export interface GeoSearchOptions {
|
|
SORT?: 'ASC' | 'DESC';
|
|
COUNT?: GeoCountArgument;
|
|
}
|
|
|
|
export function parseGeoSearchOptions(
|
|
parser: CommandParser,
|
|
options?: GeoSearchOptions
|
|
) {
|
|
if (options?.SORT) {
|
|
parser.push(options.SORT);
|
|
}
|
|
|
|
if (options?.COUNT) {
|
|
if (typeof options.COUNT === 'number') {
|
|
parser.push('COUNT', options.COUNT.toString());
|
|
} else {
|
|
parser.push('COUNT', options.COUNT.value.toString());
|
|
|
|
if (options.COUNT.ANY) {
|
|
parser.push('ANY');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export default {
|
|
IS_READ_ONLY: true,
|
|
parseCommand(
|
|
parser: CommandParser,
|
|
key: RedisArgument,
|
|
from: GeoSearchFrom,
|
|
by: GeoSearchBy,
|
|
options?: GeoSearchOptions
|
|
) {
|
|
parser.push('GEOSEARCH');
|
|
parseGeoSearchArguments(parser, key, from, by, options);
|
|
},
|
|
transformReply: undefined as unknown as () => ArrayReply<BlobStringReply>
|
|
} as const satisfies Command;
|