Skip to content
This repository was archived by the owner on Dec 2, 2024. It is now read-only.

Commit ff1ba48

Browse files
committed
Add db.getMany(keys)
Ref Level/community#101
1 parent b331481 commit ff1ba48

File tree

5 files changed

+319
-8
lines changed

5 files changed

+319
-8
lines changed

leveldown.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ const ENCODERS = [
1515
messages.Delete,
1616
messages.Batch,
1717
messages.Iterator,
18-
messages.Clear
18+
messages.Clear,
19+
messages.GetMany
1920
]
2021

2122
const DECODERS = [
2223
messages.Callback,
23-
messages.IteratorData
24+
messages.IteratorData,
25+
messages.GetManyCallback
2426
]
2527

2628
module.exports = Multilevel
@@ -34,7 +36,7 @@ function Multilevel (opts) {
3436
permanence: true,
3537
seek: false,
3638
clear: true,
37-
getMany: false,
39+
getMany: true,
3840
createIfMissing: false,
3941
errorIfExists: false
4042
})
@@ -84,6 +86,10 @@ Multilevel.prototype.createRpcStream = function (opts, proxy) {
8486
case 1:
8587
oniteratordata(res)
8688
break
89+
90+
case 2:
91+
ongetmanycallback(res)
92+
break
8793
}
8894

8995
self._flushMaybe()
@@ -131,6 +137,11 @@ Multilevel.prototype.createRpcStream = function (opts, proxy) {
131137
const req = self._requests.remove(res.id)
132138
if (req) req.callback(decodeError(res.error), decodeValue(res.value, req.valueAsBuffer))
133139
}
140+
141+
function ongetmanycallback (res) {
142+
const req = self._requests.remove(res.id)
143+
if (req) req.callback(decodeError(res.error), res.values.map(v => decodeValue(v.value, req.valueAsBuffer)))
144+
}
134145
}
135146

136147
Multilevel.prototype.forward = function (down) {
@@ -185,6 +196,21 @@ Multilevel.prototype._get = function (key, opts, cb) {
185196
this._write(req)
186197
}
187198

199+
Multilevel.prototype._getMany = function (keys, opts, cb) {
200+
if (this._db) return this._db._getMany(keys, opts, cb)
201+
202+
const req = {
203+
tag: 6,
204+
id: 0,
205+
keys: keys,
206+
valueAsBuffer: opts.asBuffer,
207+
callback: cb
208+
}
209+
210+
req.id = this._requests.add(req)
211+
this._write(req)
212+
}
213+
188214
Multilevel.prototype._put = function (key, value, opts, cb) {
189215
if (this._db) return this._db._put(key, value, opts, cb)
190216

messages.js

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ var IteratorData = exports.IteratorData = {
6666
decode: null
6767
}
6868

69+
var GetMany = exports.GetMany = {
70+
buffer: true,
71+
encodingLength: null,
72+
encode: null,
73+
decode: null
74+
}
75+
76+
var GetManyCallback = exports.GetManyCallback = {
77+
buffer: true,
78+
encodingLength: null,
79+
encode: null,
80+
decode: null
81+
}
82+
6983
defineGet()
7084
definePut()
7185
defineDelete()
@@ -74,6 +88,8 @@ defineClear()
7488
defineIterator()
7589
defineCallback()
7690
defineIteratorData()
91+
defineGetMany()
92+
defineGetManyCallback()
7793

7894
function defineGet () {
7995
Get.encodingLength = encodingLength
@@ -1115,6 +1131,241 @@ function defineIteratorData () {
11151131
}
11161132
}
11171133

1134+
function defineGetMany () {
1135+
GetMany.encodingLength = encodingLength
1136+
GetMany.encode = encode
1137+
GetMany.decode = decode
1138+
1139+
function encodingLength (obj) {
1140+
var length = 0
1141+
if (!defined(obj.id)) throw new Error("id is required")
1142+
var len = encodings.varint.encodingLength(obj.id)
1143+
length += 1 + len
1144+
if (defined(obj.keys)) {
1145+
for (var i = 0; i < obj.keys.length; i++) {
1146+
if (!defined(obj.keys[i])) continue
1147+
var len = encodings.bytes.encodingLength(obj.keys[i])
1148+
length += 1 + len
1149+
}
1150+
}
1151+
return length
1152+
}
1153+
1154+
function encode (obj, buf, offset) {
1155+
if (!offset) offset = 0
1156+
if (!buf) buf = Buffer.allocUnsafe(encodingLength(obj))
1157+
var oldOffset = offset
1158+
if (!defined(obj.id)) throw new Error("id is required")
1159+
buf[offset++] = 8
1160+
encodings.varint.encode(obj.id, buf, offset)
1161+
offset += encodings.varint.encode.bytes
1162+
if (defined(obj.keys)) {
1163+
for (var i = 0; i < obj.keys.length; i++) {
1164+
if (!defined(obj.keys[i])) continue
1165+
buf[offset++] = 18
1166+
encodings.bytes.encode(obj.keys[i], buf, offset)
1167+
offset += encodings.bytes.encode.bytes
1168+
}
1169+
}
1170+
encode.bytes = offset - oldOffset
1171+
return buf
1172+
}
1173+
1174+
function decode (buf, offset, end) {
1175+
if (!offset) offset = 0
1176+
if (!end) end = buf.length
1177+
if (!(end <= buf.length && offset <= buf.length)) throw new Error("Decoded message is not valid")
1178+
var oldOffset = offset
1179+
var obj = {
1180+
id: 0,
1181+
keys: []
1182+
}
1183+
var found0 = false
1184+
while (true) {
1185+
if (end <= offset) {
1186+
if (!found0) throw new Error("Decoded message is not valid")
1187+
decode.bytes = offset - oldOffset
1188+
return obj
1189+
}
1190+
var prefix = varint.decode(buf, offset)
1191+
offset += varint.decode.bytes
1192+
var tag = prefix >> 3
1193+
switch (tag) {
1194+
case 1:
1195+
obj.id = encodings.varint.decode(buf, offset)
1196+
offset += encodings.varint.decode.bytes
1197+
found0 = true
1198+
break
1199+
case 2:
1200+
obj.keys.push(encodings.bytes.decode(buf, offset))
1201+
offset += encodings.bytes.decode.bytes
1202+
break
1203+
default:
1204+
offset = skip(prefix & 7, buf, offset)
1205+
}
1206+
}
1207+
}
1208+
}
1209+
1210+
function defineGetManyCallback () {
1211+
var Value = GetManyCallback.Value = {
1212+
buffer: true,
1213+
encodingLength: null,
1214+
encode: null,
1215+
decode: null
1216+
}
1217+
1218+
defineValue()
1219+
1220+
function defineValue () {
1221+
Value.encodingLength = encodingLength
1222+
Value.encode = encode
1223+
Value.decode = decode
1224+
1225+
function encodingLength (obj) {
1226+
var length = 0
1227+
if (defined(obj.value)) {
1228+
var len = encodings.bytes.encodingLength(obj.value)
1229+
length += 1 + len
1230+
}
1231+
return length
1232+
}
1233+
1234+
function encode (obj, buf, offset) {
1235+
if (!offset) offset = 0
1236+
if (!buf) buf = Buffer.allocUnsafe(encodingLength(obj))
1237+
var oldOffset = offset
1238+
if (defined(obj.value)) {
1239+
buf[offset++] = 10
1240+
encodings.bytes.encode(obj.value, buf, offset)
1241+
offset += encodings.bytes.encode.bytes
1242+
}
1243+
encode.bytes = offset - oldOffset
1244+
return buf
1245+
}
1246+
1247+
function decode (buf, offset, end) {
1248+
if (!offset) offset = 0
1249+
if (!end) end = buf.length
1250+
if (!(end <= buf.length && offset <= buf.length)) throw new Error("Decoded message is not valid")
1251+
var oldOffset = offset
1252+
var obj = {
1253+
value: null
1254+
}
1255+
while (true) {
1256+
if (end <= offset) {
1257+
decode.bytes = offset - oldOffset
1258+
return obj
1259+
}
1260+
var prefix = varint.decode(buf, offset)
1261+
offset += varint.decode.bytes
1262+
var tag = prefix >> 3
1263+
switch (tag) {
1264+
case 1:
1265+
obj.value = encodings.bytes.decode(buf, offset)
1266+
offset += encodings.bytes.decode.bytes
1267+
break
1268+
default:
1269+
offset = skip(prefix & 7, buf, offset)
1270+
}
1271+
}
1272+
}
1273+
}
1274+
1275+
GetManyCallback.encodingLength = encodingLength
1276+
GetManyCallback.encode = encode
1277+
GetManyCallback.decode = decode
1278+
1279+
function encodingLength (obj) {
1280+
var length = 0
1281+
if (!defined(obj.id)) throw new Error("id is required")
1282+
var len = encodings.varint.encodingLength(obj.id)
1283+
length += 1 + len
1284+
if (defined(obj.error)) {
1285+
var len = encodings.string.encodingLength(obj.error)
1286+
length += 1 + len
1287+
}
1288+
if (defined(obj.values)) {
1289+
for (var i = 0; i < obj.values.length; i++) {
1290+
if (!defined(obj.values[i])) continue
1291+
var len = Value.encodingLength(obj.values[i])
1292+
length += varint.encodingLength(len)
1293+
length += 1 + len
1294+
}
1295+
}
1296+
return length
1297+
}
1298+
1299+
function encode (obj, buf, offset) {
1300+
if (!offset) offset = 0
1301+
if (!buf) buf = Buffer.allocUnsafe(encodingLength(obj))
1302+
var oldOffset = offset
1303+
if (!defined(obj.id)) throw new Error("id is required")
1304+
buf[offset++] = 8
1305+
encodings.varint.encode(obj.id, buf, offset)
1306+
offset += encodings.varint.encode.bytes
1307+
if (defined(obj.error)) {
1308+
buf[offset++] = 18
1309+
encodings.string.encode(obj.error, buf, offset)
1310+
offset += encodings.string.encode.bytes
1311+
}
1312+
if (defined(obj.values)) {
1313+
for (var i = 0; i < obj.values.length; i++) {
1314+
if (!defined(obj.values[i])) continue
1315+
buf[offset++] = 26
1316+
varint.encode(Value.encodingLength(obj.values[i]), buf, offset)
1317+
offset += varint.encode.bytes
1318+
Value.encode(obj.values[i], buf, offset)
1319+
offset += Value.encode.bytes
1320+
}
1321+
}
1322+
encode.bytes = offset - oldOffset
1323+
return buf
1324+
}
1325+
1326+
function decode (buf, offset, end) {
1327+
if (!offset) offset = 0
1328+
if (!end) end = buf.length
1329+
if (!(end <= buf.length && offset <= buf.length)) throw new Error("Decoded message is not valid")
1330+
var oldOffset = offset
1331+
var obj = {
1332+
id: 0,
1333+
error: "",
1334+
values: []
1335+
}
1336+
var found0 = false
1337+
while (true) {
1338+
if (end <= offset) {
1339+
if (!found0) throw new Error("Decoded message is not valid")
1340+
decode.bytes = offset - oldOffset
1341+
return obj
1342+
}
1343+
var prefix = varint.decode(buf, offset)
1344+
offset += varint.decode.bytes
1345+
var tag = prefix >> 3
1346+
switch (tag) {
1347+
case 1:
1348+
obj.id = encodings.varint.decode(buf, offset)
1349+
offset += encodings.varint.decode.bytes
1350+
found0 = true
1351+
break
1352+
case 2:
1353+
obj.error = encodings.string.decode(buf, offset)
1354+
offset += encodings.string.decode.bytes
1355+
break
1356+
case 3:
1357+
var len = varint.decode(buf, offset)
1358+
offset += varint.decode.bytes
1359+
obj.values.push(Value.decode(buf, offset, offset + len))
1360+
offset += Value.decode.bytes
1361+
break
1362+
default:
1363+
offset = skip(prefix & 7, buf, offset)
1364+
}
1365+
}
1366+
}
1367+
}
1368+
11181369
function defined (val) {
11191370
return val !== null && val !== undefined && (typeof val !== 'number' || !isNaN(val))
11201371
}

schema.proto

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,19 @@ message IteratorData {
6868
optional bytes key = 3;
6969
optional bytes value = 4;
7070
}
71+
72+
message GetMany {
73+
required uint32 id = 1;
74+
repeated bytes keys = 2;
75+
}
76+
77+
message GetManyCallback {
78+
required uint32 id = 1;
79+
optional string error = 2;
80+
repeated Value values = 3;
81+
82+
// Wrapped to support undefined values
83+
message Value {
84+
optional bytes value = 1;
85+
}
86+
}

0 commit comments

Comments
 (0)