|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using ZeroLevel.Services.Serialization;
|
|
|
|
|
|
|
|
|
|
namespace ZeroLevel.HNSW
|
|
|
|
|
{
|
|
|
|
|
internal class LALLinks
|
|
|
|
|
: IBinarySerializable
|
|
|
|
|
{
|
|
|
|
|
private ConcurrentDictionary<int, int[]> _set = new ConcurrentDictionary<int, int[]>();
|
|
|
|
|
internal IDictionary<int, int[]> Links => _set;
|
|
|
|
|
|
|
|
|
|
private readonly int[] _empty = new int[0];
|
|
|
|
|
internal int Count => _set.Count;
|
|
|
|
|
|
|
|
|
|
public LALLinks()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal IEnumerable<(int, int)> FindLinksForId(int id)
|
|
|
|
|
{
|
|
|
|
|
if (_set.ContainsKey(id))
|
|
|
|
|
{
|
|
|
|
|
return _set[id].Select(v => (id, v));
|
|
|
|
|
}
|
|
|
|
|
return Enumerable.Empty<(int, int)>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal int[] FindNeighbors(int id)
|
|
|
|
|
{
|
|
|
|
|
if (_set.ContainsKey(id))
|
|
|
|
|
{
|
|
|
|
|
return _set[id];
|
|
|
|
|
}
|
|
|
|
|
return _empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal IEnumerable<(int, int)> Items()
|
|
|
|
|
{
|
|
|
|
|
return _set
|
|
|
|
|
.SelectMany(pair => _set[pair.Key]
|
|
|
|
|
.Select(v => (pair.Key, v)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
_set.Clear();
|
|
|
|
|
_set = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Serialize(IBinaryWriter writer)
|
|
|
|
|
{
|
|
|
|
|
writer.WriteInt32(_set.Count);
|
|
|
|
|
foreach (var record in _set)
|
|
|
|
|
{
|
|
|
|
|
writer.WriteInt32(record.Key);
|
|
|
|
|
writer.WriteCollection(record.Value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Deserialize(IBinaryReader reader)
|
|
|
|
|
{
|
|
|
|
|
_set.Clear();
|
|
|
|
|
_set = null;
|
|
|
|
|
var count = reader.ReadInt32();
|
|
|
|
|
_set = new ConcurrentDictionary<int, int[]>(1, count);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
var id = reader.ReadInt32();
|
|
|
|
|
var links_count = reader.ReadInt32();
|
|
|
|
|
_set[id] = new int[links_count];
|
|
|
|
|
for (int l = 0; l < links_count; l++)
|
|
|
|
|
{
|
|
|
|
|
_set[id][l] = reader.ReadInt32();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|