// function: // Searches sortedArray[first]..sortedArray[last] for key. // returns: index of the matching element if it finds key, // otherwise -(index where it could be inserted)-1. // parameters: // sortedArray in array of sorted (ascending) values. // first, last in lower and upper subscript bounds // key in value to search for. // returns: // index of key, or -insertion_position -1 if key is not // in the array. This value can easily be // transformed into the position to insert it. public bool Search(ChunkChecksum key, out long start) { start = -1; if (ChunkCount == 0) return false; int idx = Array.BinarySearch(Chunks, key); if (idx >= 0) { start = idx; return true; } else { return false; } }
public void CalculateChecksum(byte[] data, long start, long size, ChunkChecksum K) { unsafe { fixed (byte *p = &data[start]) { var i = (UInt64*)p; K.V = i[0]; } } //K.Adler32 = 0; K.Adler32 = Adler32.Check(1, data, start, size); }
SameBlock FindBlock(ChunkedFile sourceTree, long targetFileStartOffset) { if (mTargetSize - targetFileStartOffset < BlockSize) return null; long preDataSize = targetFileStartOffset - mTargetCDataBaseOffset; // rea the current data part in to memory ChunkChecksum checksum = new ChunkChecksum(); sourceTree.CalculateChecksum(mTargetCData, preDataSize, BlockSize, checksum); long foundIndex; if (sourceTree.Search(checksum, out foundIndex)) { // we found something SameBlock bestMatch = new SameBlock(); bestMatch.SourceOffset = sourceTree.Chunks[foundIndex].Offset; bestMatch.TargetOffset = targetFileStartOffset; bestMatch.Size = 0; // default to 0. because they can all be mismatches as well // inreae match size if possible, also check if it is a match at all long matchCount = 0; while ((sourceTree.Chunks[foundIndex].Checksum == checksum) && ((MaximumMatches == 0) || (matchCount < MaximumMatches))) { // check if this one is better than the current match SameBlock match = new SameBlock(); match.SourceOffset = sourceTree.Chunks[foundIndex].Offset; match.TargetOffset = targetFileStartOffset; match.Size = 0; // default to 0. could be a mismatch with the same key ImproveSameBlockMatch(match, bestMatch.Size); if (match.Size > bestMatch.Size) { bestMatch = match; } foundIndex++; matchCount++; } // TODO: Emit debugging information here if in verbose mode. if (bestMatch.Size == 0) { return null; } else { return bestMatch; } } else { return null; } }