public static VectorNode DeserializeNode( long vecOffset, long postingsOffset, long componentCount, long weight, long terminator, Stream vectorStream, IStringModel tokenizer) { var vector = tokenizer.DeserializeVector(vecOffset, (int)componentCount, vectorStream); var node = new VectorNode(postingsOffset, vecOffset, terminator, weight, componentCount, vector); return(node); }
private Hit ClosestMatchInPage( Vector vector, Stream indexStream, Stream vectorStream, IStringModel model ) { Span <byte> block = stackalloc byte[VectorNode.BlockSize]; var read = indexStream.Read(block); VectorNode best = null; float highscore = 0; while (read > 0) { var vecOffset = BitConverter.ToInt64(block.Slice(0, sizeof(long))); var componentCount = BitConverter.ToInt64(block.Slice(sizeof(long) + sizeof(long), sizeof(long))); var cursorVector = model.DeserializeVector(vecOffset, (int)componentCount, vectorStream); var cursorTerminator = BitConverter.ToInt64(block.Slice(sizeof(long) + sizeof(long) + sizeof(long) + sizeof(long), sizeof(long))); var postingsOffset = BitConverter.ToInt64(block.Slice(sizeof(long), sizeof(long))); var angle = model.CosAngle(cursorVector, vector); if (angle >= model.IdenticalAngle) { if (best == null || angle > highscore) { highscore = angle; best = new VectorNode(cursorVector); best.PostingsOffsets = new List <long> { postingsOffset }; } else if (angle == highscore) { if (best.PostingsOffsets == null) { best.PostingsOffsets = new List <long> { best.PostingsOffset, postingsOffset }; } else { best.PostingsOffsets.Add(postingsOffset); } } break; } else if (angle > model.FoldAngle) { if (best == null || angle > highscore) { highscore = angle; best = new VectorNode(cursorVector); best.PostingsOffsets = new List <long> { postingsOffset }; } else if (angle == highscore) { if (best.PostingsOffsets == null) { best.PostingsOffsets = new List <long> { best.PostingsOffset, postingsOffset }; } else { best.PostingsOffsets.Add(postingsOffset); } } // We need to determine if we can traverse further left. bool canGoLeft = cursorTerminator == 0 || cursorTerminator == 1; if (canGoLeft) { // There exists either a left and a right child or just a left child. // Either way, we want to go left and the next node in bitmap is the left child. read = indexStream.Read(block); } else { // There is no left child. break; } } else { if (best == null || angle > highscore) { highscore = angle; best = new VectorNode(cursorVector); best.PostingsOffsets = new List <long> { postingsOffset }; } else if (angle == highscore) { if (best.PostingsOffsets == null) { best.PostingsOffsets = new List <long> { best.PostingsOffset, postingsOffset }; } else { best.PostingsOffsets.Add(postingsOffset); } } // We need to determine if we can traverse further to the right. if (cursorTerminator == 0) { // There exists a left and a right child. // Next node in bitmap is the left child. // To find cursor's right child we must skip over the left tree. SkipTree(indexStream); read = indexStream.Read(block); } else if (cursorTerminator == 2) { // Next node in bitmap is the right child, // which is good because we want to go right. read = indexStream.Read(block); } else { // There is no right child. break; } } } return(new Hit { Score = highscore, Node = best }); }