public void HashSearch(IOStream f, SumStruct s, MapFile buf, int len, Sum _sum) { int offset, end, backup; UInt32 k; int wantI; byte[] sum2 = new byte[CheckSum.SUM_LENGTH]; UInt32 s1, s2, sum; int more; byte[] map; wantI = 0; if (options.verbose > 2) { Log.WriteLine("hash search ob=" + s.bLength + " len=" + len); } k = (UInt32)Math.Min(len, s.bLength); int off = buf.MapPtr(0, (int)k); map = buf.p; UInt32 g = s.sums[0].sum1; sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; if (options.verbose > 3) { Log.WriteLine("sum=" + sum + " k=" + k); } offset = 0; end = (int)(len + 1 - s.sums[s.count - 1].len); if (options.verbose > 3) { Log.WriteLine("hash search s.bLength=" + s.bLength + " len=" + len + " count=" + s.count); } do { UInt32 t = GetTag2(s1, s2); bool doneCsum2 = false; int j = tagTable[t]; if (options.verbose > 4) { Log.WriteLine("offset=" + offset + " sum=" + sum); } if (j == NULL_TAG) { goto null_tag; } sum = (s1 & 0xffff) | (s2 << 16); tagHits++; do { UInt32 l; int i = ((Target)targets[j]).i; if (sum != s.sums[i].sum1) { continue; } l = (UInt32)Math.Min(s.bLength, len - offset); if (l != s.sums[i].len) { continue; } if (options.verbose > 3) { Log.WriteLine("potential match at " + offset + " target=" + j + " " + i + " sum=" + sum); } if (!doneCsum2) { off = buf.MapPtr(offset, (int)l); map = buf.p; CheckSum cs = new CheckSum(options); sum2 = cs.GetChecksum2(map, off, (int)l); doneCsum2 = true; } if (Util.MemCmp(sum2, 0, s.sums[i].sum2, 0, s.s2Length) != 0) { falseAlarms++; continue; } if (i != wantI && wantI < s.count && (!options.inplace || options.makeBackups || s.sums[wantI].offset >= offset || (s.sums[wantI].flags & SUMFLG_SAME_OFFSET) != 0) && sum == s.sums[wantI].sum1 && Util.MemCmp(sum2, 0, s.sums[wantI].sum2, 0, s.s2Length) == 0) { i = wantI; } set_want_i: wantI = i + 1; Matched(f, s, buf, offset, i, _sum); offset += (int)(s.sums[i].len - 1); k = (UInt32)Math.Min(s.bLength, len - offset); off = buf.MapPtr(offset, (int)k); sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; matches++; break; } while (++j < s.count && ((Target)targets[j]).t == t); null_tag: backup = offset - lastMatch; if (backup < 0) { backup = 0; } more = (offset + k) < len ? 1 : 0; off = buf.MapPtr(offset - backup, (int)(k + more + backup)) + backup; s1 -= (UInt32)(CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET); s2 -= (UInt32)(k * CheckSum.ToInt(map[off]) + CheckSum.CHAR_OFFSET); off = (k + off >= map.Length) ? (int)(map.Length - k - 1) : off; if (more != 0) { s1 += (UInt32)(CheckSum.ToInt(map[k + off]) + CheckSum.CHAR_OFFSET); s2 += s1; } else { --k; } if (backup >= CHUNK_SIZE + s.bLength && end - offset > CHUNK_SIZE) { Matched(f, s, buf, (int)(offset - s.bLength), -2, _sum); } } while (++offset < end); Matched(f, s, buf, len, -1, _sum); buf.MapPtr(len - 1, 1); }
public void HashSearch(IoStream f, SumStruct s, MapFile buf, int len, Sum _sum) { int offset, end, backup; UInt32 k; int wantI; var sum2 = new byte[CheckSum.SumLength]; UInt32 s1, s2, sum; int more; byte[] map; wantI = 0; if (_options.Verbose > 2) { Log.WriteLine("hash search ob=" + s.BLength + " len=" + len); } k = (UInt32)Math.Min(len, s.BLength); var off = buf.MapPtr(0, (int)k); map = buf.P; var g = s.Sums[0].Sum1; sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; if (_options.Verbose > 3) { Log.WriteLine("sum=" + sum + " k=" + k); } offset = 0; end = (int)(len + 1 - s.Sums[s.Count - 1].Len); if (_options.Verbose > 3) { Log.WriteLine("hash search s.bLength=" + s.BLength + " len=" + len + " count=" + s.Count); } do { var t = GetTag2(s1, s2); var doneCsum2 = false; var j = _tagTable[t]; if (_options.Verbose > 4) { Log.WriteLine("offset=" + offset + " sum=" + sum); } if (j == NullTag) { goto null_tag; } sum = (s1 & 0xffff) | (s2 << 16); _tagHits++; do { UInt32 l; var i = _targets[j].I; if (sum != s.Sums[i].Sum1) { continue; } l = (UInt32)Math.Min(s.BLength, len - offset); if (l != s.Sums[i].Len) { continue; } if (_options.Verbose > 3) { Log.WriteLine("potential match at " + offset + " target=" + j + " " + i + " sum=" + sum); } if (!doneCsum2) { off = buf.MapPtr(offset, (int)l); map = buf.P; var cs = new CheckSum(_options); sum2 = cs.GetChecksum2(map, off, (int)l); doneCsum2 = true; } if (Util.MemoryCompare(sum2, 0, s.Sums[i].Sum2, 0, s.S2Length) != 0) { _falseAlarms++; continue; } if (i != wantI && wantI < s.Count && (!_options.Inplace || _options.MakeBackups || s.Sums[wantI].Offset >= offset || (s.Sums[wantI].Flags & SumflgSameOffset) != 0) && sum == s.Sums[wantI].Sum1 && Util.MemoryCompare(sum2, 0, s.Sums[wantI].Sum2, 0, s.S2Length) == 0) { i = wantI; } //set_want_i: wantI = i + 1; Matched(f, s, buf, offset, i, _sum); offset += (int)(s.Sums[i].Len - 1); k = (UInt32)Math.Min(s.BLength, len - offset); off = buf.MapPtr(offset, (int)k); sum = CheckSum.GetChecksum1(map, off, (int)k); s1 = sum & 0xFFFF; s2 = sum >> 16; _matches++; break; } while (++j < s.Count && _targets[j].T == t); null_tag: backup = offset - _lastMatch; if (backup < 0) { backup = 0; } more = (offset + k) < len ? 1 : 0; off = buf.MapPtr(offset - backup, (int)(k + more + backup)) + backup; s1 -= (UInt32)(CheckSum.ToInt(map[off]) + CheckSum.CharOffset); s2 -= (UInt32)(k * CheckSum.ToInt(map[off]) + CheckSum.CharOffset); off = (k + off >= map.Length) ? (int)(map.Length - k - 1) : off; if (more != 0) { s1 += (UInt32)(CheckSum.ToInt(map[k + off]) + CheckSum.CharOffset); s2 += s1; } else { --k; } if (backup >= ChunkSize + s.BLength && end - offset > ChunkSize) { Matched(f, s, buf, (int)(offset - s.BLength), -2, _sum); } } while (++offset < end); Matched(f, s, buf, len, -1, _sum); buf.MapPtr(len - 1, 1); }