/// <summary> /// Performs the actual encoding of a chunk of data into the VCDiff format /// </summary> /// <param name="dictionary">The dictionary hash table</param> /// <param name="oldData">The data for the dictionary hash table</param> /// <param name="hash">The rolling hash object</param> /// <param name="interleaved">Whether to interleave the data or not</param> /// <param name="checksum">Whether to include checksums for each window</param> public ChunkEncoder(BlockHash dictionary, IByteBuffer oldData, RollingHash hash, bool interleaved = false, bool checksum = false) { hasChecksum = checksum; hasher = hash; this.oldData = oldData; this.dictionary = dictionary; this.interleaved = interleaved; }
/// <summary> /// The easy public structure for encoding into a vcdiff format /// Simply instantiate it with the proper streams and use the Encode() function. /// Does not check if data is equal already. You will need to do that. /// Returns VCDiffResult: should always return success, unless either the dict or the target streams have 0 bytes /// See the VCDecoder for decoding vcdiff format /// </summary> /// <param name="dict">The dictionary (previous data)</param> /// <param name="target">The new data</param> /// <param name="sout">The output stream</param> /// <param name="maxBufferSize">The maximum buffer size for window chunking. It is in Megabytes. 2 would mean 2 megabytes etc. Default is 1.</param> public VCCoder(Stream dict, Stream target, Stream sout, int maxBufferSize = 1) { if (maxBufferSize <= 0) { maxBufferSize = 1; } oldData = new ByteStreamReader(dict); newData = new ByteStreamReader(target); this.sout = new ByteStreamWriter(sout); hasher = new RollingHash(BlockHash.BlockSize); bufferSize = maxBufferSize * 1024 * 1024; }
/// <summary> /// Create a hash lookup table for the data /// </summary> /// <param name="sin">the data to create the table for</param> /// <param name="offset">the offset usually 0</param> /// <param name="hasher">the hashing method</param> public BlockHash(IByteBuffer sin, int offset, RollingHash hasher) { maxMatchesToCheck = (blockSize >= 32) ? 32 : (32 * (32 / blockSize)); this.hasher = hasher; Source = sin; this.offset = offset; TableSize = CalcTableSize(); if (TableSize == 0) { throw new Exception("BlockHash Table Size is Invalid == 0"); } hashTableMask = (ulong)TableSize - 1; hashTable = new long[TableSize]; nextBlockTable = new long[BlocksCount]; lastBlockTable = new long[BlocksCount]; lastBlockAdded = -1; SetTablesToInvalid(); }