fromJson static method
Reconstruct an HnswIndex from toJson output.
Implementation
static HnswIndex fromJson(Map<String, Object?> j) {
final dim = (j['dim'] as num).toInt();
final metric = VectorMetric.values.firstWhere(
(m) => m.name == j['metric'],
orElse: () => VectorMetric.l2sq,
);
final idx = HnswIndex(
dim,
m: (j['m'] as num?)?.toInt() ?? 16,
efConstruction: (j['efConstruction'] as num?)?.toInt() ?? 40,
efSearch: (j['efSearch'] as num?)?.toInt() ?? 16,
defaultMetric: metric,
);
final rawIds = (j['ids'] as List).cast<Object?>();
idx._ids.addAll([
for (final e in rawIds)
if (e is Map && e['__tomb__'] == true) HnswIndex._tombstone else e
]);
idx._tombstoneCount = idx._ids.where((e) => e == _tombstone).length;
idx._nodeLevel
.addAll((j['nodeLevel'] as List).cast<num>().map((n) => n.toInt()));
idx._links.addAll([
for (final perNode in (j['links'] as List).cast<List>())
[
for (final perLayer in perNode.cast<List>())
[for (final v in perLayer.cast<num>()) v.toInt()],
],
]);
idx._entry = (j['entry'] as num).toInt();
idx._topLayer = (j['topLayer'] as num).toInt();
idx._data = _decodeF32Slice(j['data'] as String);
final n = idx._ids.length;
if (idx._data.length != n * dim) {
throw FormatException(
'HnswIndex.fromJson: data length ${idx._data.length} '
'!= ids $n * dim $dim',
);
}
return idx;
}