在 etcd v3.0.x 中,我如何请求具有给定前缀的所有键?
In etcd v3.0.x, how do I request all keys with a given prefix?
在 etcd 3.0.x 中,引入了一个新的 API,我正在阅读它。在 RangeRequest
对象中,我不清楚一件事。在 description of the property range_end
中,它表示:
If the range_end is one bit larger than the given key,
then the range requests get the all keys with the prefix (the given key).
这是完整的文本,以提供一些上下文:
// key is the first key for the range. If range_end is not given, the request only looks up key.
bytes key = 1;
// range_end is the upper bound on the requested range [key, range_end).
// If range_end is '[=11=]', the range is all keys >= key.
// If the range_end is one bit larger than the given key,
// then the range requests get the all keys with the prefix (the given key).
// If both key and range_end are '[=11=]', then range requests returns all keys.
bytes range_end = 2;
我的问题是:
是什么意思
If the range_end is one bit larger than the given key
?这是否意味着 range_end
比 key
长 1 位?这是否意味着当解释为整数时它必须是 key+1
?如果是后者,采用哪种编码方式?
比key
的最后一个字节大一位。
例如,如果 key
是“09903x”,那么 range_end
应该是“09903y”。
发送到etcd服务器时只有字节流,所以要关心驱动的序列化,确定range_end
.
的值
有一个 PR 解决了这个困惑。
If range_end is key plus one (e.g., "aa"+1 == "ab", "a\xff"+1 == "b"),
then the range request gets all keys prefixed with key.
更新:
var key = "/aaa"
var range_end = "/aa" + String.fromCharCode("a".charCodeAt(2) + 1);
这里有一个很棒的 TypeScript 示例:https://github.com/mixer/etcd3/blob/7691f9bf227841e268c3aeeb7461ad71872df878/src/util.ts#L25
工作 js 示例 TextEncoder/TextDecoder:
function endRangeForPrefix(value) {
let textEncoder = new TextEncoder();
let encodeValue = textEncoder.encode(value);
for (let i = encodeValue.length - 1; i >= 0; i--) {
if (encodeValue[i] < 0xff) {
encodeValue[i]++;
encodeValue = encodeValue.slice(0, i + 1);
let textDecoder = new TextDecoder();
let decode = textDecoder.decode(encodeValue);
return decode;
}
}
return '';
}
我正在使用 python aioetcd3。我也遇到了同样的问题,不过在他的源码里找到了方法
aioetcd3/utils.py 第 14 行
def increment_last_byte(byte_string):
s = bytearray(to_bytes(byte_string))
for i in range(len(s) - 1, -1, -1):
if s[i] < 0xff:
s[i] += 1
return bytes(s[:i+1])
else:
return b'\x00'
用法:
await Client().delete([db_key, increment_last_byte(db_key)], prev_kv=True)
在 etcd 3.0.x 中,引入了一个新的 API,我正在阅读它。在 RangeRequest
对象中,我不清楚一件事。在 description of the property range_end
中,它表示:
If the range_end is one bit larger than the given key, then the range requests get the all keys with the prefix (the given key).
这是完整的文本,以提供一些上下文:
// key is the first key for the range. If range_end is not given, the request only looks up key.
bytes key = 1;
// range_end is the upper bound on the requested range [key, range_end).
// If range_end is '[=11=]', the range is all keys >= key.
// If the range_end is one bit larger than the given key,
// then the range requests get the all keys with the prefix (the given key).
// If both key and range_end are '[=11=]', then range requests returns all keys.
bytes range_end = 2;
我的问题是:
是什么意思If the range_end is one bit larger than the given key
?这是否意味着 range_end
比 key
长 1 位?这是否意味着当解释为整数时它必须是 key+1
?如果是后者,采用哪种编码方式?
比key
的最后一个字节大一位。
例如,如果 key
是“09903x”,那么 range_end
应该是“09903y”。
发送到etcd服务器时只有字节流,所以要关心驱动的序列化,确定range_end
.
有一个 PR 解决了这个困惑。
If range_end is key plus one (e.g., "aa"+1 == "ab", "a\xff"+1 == "b"), then the range request gets all keys prefixed with key.
更新:
var key = "/aaa"
var range_end = "/aa" + String.fromCharCode("a".charCodeAt(2) + 1);
这里有一个很棒的 TypeScript 示例:https://github.com/mixer/etcd3/blob/7691f9bf227841e268c3aeeb7461ad71872df878/src/util.ts#L25
工作 js 示例 TextEncoder/TextDecoder:
function endRangeForPrefix(value) {
let textEncoder = new TextEncoder();
let encodeValue = textEncoder.encode(value);
for (let i = encodeValue.length - 1; i >= 0; i--) {
if (encodeValue[i] < 0xff) {
encodeValue[i]++;
encodeValue = encodeValue.slice(0, i + 1);
let textDecoder = new TextDecoder();
let decode = textDecoder.decode(encodeValue);
return decode;
}
}
return '';
}
我正在使用 python aioetcd3。我也遇到了同样的问题,不过在他的源码里找到了方法
aioetcd3/utils.py 第 14 行
def increment_last_byte(byte_string):
s = bytearray(to_bytes(byte_string))
for i in range(len(s) - 1, -1, -1):
if s[i] < 0xff:
s[i] += 1
return bytes(s[:i+1])
else:
return b'\x00'
用法:
await Client().delete([db_key, increment_last_byte(db_key)], prev_kv=True)