fromJson static method

HnswIndex fromJson(
  1. Map<String, Object?> j
)

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;
}