private static ImmutableList <TKey> WriteMatchDataAndReturnReferencedKeys(IndexData <TKey> data, BinaryWriter writer) { if (data == null) { throw new ArgumentNullException("data"); } if (writer == null) { throw new ArgumentNullException("writer"); } var allKeys = new List <TKey>(); var allTokens = data.GetAllTokens(); writer.Write(allTokens.Count); foreach (var token in allTokens) { var matchesForToken = data.GetMatches(token); writer.Write(token); writer.Write(matchesForToken.Count); foreach (var match in matchesForToken) { var keyIndexData = allKeys .Select((key, index) => new { Key = key, Index = index }) .FirstOrDefault(k => data.KeyComparer.Equals(k.Key, match.Key)); int keyIndex; if (keyIndexData == null) { allKeys.Add(match.Key); keyIndex = allKeys.Count - 1; } else { keyIndex = keyIndexData.Index; } writer.Write(keyIndex); writer.Write(match.Weight); if (match.SourceLocationsIfRecorded == null) { writer.Write(0); } else { writer.Write(match.SourceLocationsIfRecorded.Count); foreach (var sourceLocation in match.SourceLocationsIfRecorded) { writer.Write(sourceLocation.SourceFieldIndex); writer.Write(sourceLocation.TokenIndex); writer.Write(sourceLocation.SourceIndex); writer.Write(sourceLocation.SourceTokenLength); writer.Write(sourceLocation.MatchWeightContribution); } } } } return(allKeys.ToImmutableList()); }
/// <summary> /// This will throw an ArgumentNullException for null source or stream references or an IndexDataSerialisationException if the data read from the stream is invalid /// </summary> public static void Serialise(IndexData <TKey> source, Stream stream) { if (source == null) { throw new ArgumentNullException("source"); } if (stream == null) { throw new ArgumentNullException("stream"); } byte[] matchData; ImmutableList <TKey> allKeys; using (var matchDataMemoryStream = new MemoryStream()) { using (var matchDataWriter = new BinaryWriter(matchDataMemoryStream)) { allKeys = WriteMatchDataAndReturnReferencedKeys(source, matchDataWriter); matchData = matchDataMemoryStream.ToArray(); } } using (var writer = new BinaryWriter(stream)) { writer.Write("INDEXDATA\n"); writer.Write("KEYCOMPARER\n"); SerialiseItem(source.KeyComparer, writer); writer.Write("STRINGNORMALISER\n"); SerialiseItem(source.TokenComparer, writer); writer.Write("KEYS\n"); SerialiseItem(allKeys, writer); writer.Write("MATCHES\n"); writer.Write(matchData); } }