queryRange method
Range query: returns docs where field is in min, max.
Implementation
Future<Map<String, Uint8List>> queryRange(
String collection,
int fieldHash,
Uint8List min,
Uint8List max,
List<int> andTags, {
int limit = 0,
}) async {
final collBytes = utf8.encode(collection);
// [req_id:4][op:1][coll_len:2][coll][field_hash:8][min_len:2][min][max_len:2][max][and_count:1][and_tags:NĂ—8B][limit:4]
final size =
4 + 1 + 2 + collBytes.length +
8 + 2 + min.length + 2 + max.length +
1 + andTags.length * 8 + 4;
final frame = ByteData(size);
final view = frame.buffer.asUint8List();
var pos = 0;
pos += 4; // req_id
frame.setUint8(pos, opQueryRange);
pos += 1;
frame.setUint16(pos, collBytes.length, Endian.little);
pos += 2;
view.setRange(pos, pos + collBytes.length, collBytes);
pos += collBytes.length;
frame.setUint64(pos, fieldHash, Endian.little);
pos += 8;
frame.setUint16(pos, min.length, Endian.little);
pos += 2;
view.setRange(pos, pos + min.length, min);
pos += min.length;
frame.setUint16(pos, max.length, Endian.little);
pos += 2;
view.setRange(pos, pos + max.length, max);
pos += max.length;
frame.setUint8(pos, andTags.length);
pos += 1;
for (final th in andTags) {
frame.setUint64(pos, th, Endian.little);
pos += 8;
}
frame.setUint32(pos, limit, Endian.little);
final completer = Completer<WsResult>();
_pipelineQueue.add(_PendingOp(view, completer));
_scheduleFlush();
final resp = await completer.future.timeout(
const Duration(seconds: 60),
onTimeout: () => throw TimeoutException('QUERY_RANGE timeout'),
);
if (resp.isDenied) throw WsDeniedException('QUERY_RANGE: ${utf8.decode(resp.data)}');
if (resp.isError) throw WsException('QUERY_RANGE: ${utf8.decode(resp.data)}');
final results = <String, Uint8List>{};
if (resp.data.length < 4) return results;
final bd = ByteData.sublistView(resp.data);
final count = bd.getUint32(0, Endian.little);
var rpos = 4;
for (var i = 0; i < count; i++) {
if (rpos + 2 > resp.data.length) break;
final klen = bd.getUint16(rpos, Endian.little);
rpos += 2;
if (rpos + klen > resp.data.length) break;
final key = utf8.decode(resp.data.sublist(rpos, rpos + klen));
rpos += klen;
if (rpos + 4 > resp.data.length) break;
final dlen = bd.getUint32(rpos, Endian.little);
rpos += 4;
if (rpos + dlen > resp.data.length) break;
results[key] = resp.data.sublist(rpos, rpos + dlen);
rpos += dlen;
}
return results;
}