public static String GetFingerprint(byte[] bytes) { Hashdeep hashdeep = new Hashdeep(); byte[] hash = hashdeep.ComputeHash(bytes); StringBuilder sb = new StringBuilder(); foreach (byte t in hash) { sb.Append(t.ToString("x2")); } return(sb.ToString()); }
public void Put(int key1, int key2, int key3, byte[] value) { if (!CanWrite) { throw new InvalidOperationException(); } if (value == null) { value = new byte[0]; } value = (byte[])value.Clone(); if (Obfuscation) { uint[] seeds = new[] { (uint)key1, (uint)key2, (uint)key3 }; PerformSymmetricObfuscation(value, seeds); } if (TestFor(key1, key2, key3)) { Update(key1, key2, key3, value); return; } if (putCommand == null) { putCommand = connection.CreateCommand(); putCommand.CommandText = "INSERT INTO entries (key1, key2, key3, segment, offset, length) VALUES (@key1,@key2,@key3,@segment,@offset,@length)"; putCommand.Parameters.Add("@key1", DbType.Int32); putCommand.Parameters.Add("@key2", DbType.Int32); putCommand.Parameters.Add("@key3", DbType.Int32); putCommand.Parameters.Add("@segment", DbType.Int32); putCommand.Parameters.Add("@offset", DbType.Int64); putCommand.Parameters.Add("@length", DbType.Int32); } string itemHash = Hashdeep.GetFingerprint(value); if (!dedupTuples.ContainsKey(itemHash)) { int usableSegmentId = FindUsableSegment(value.Length + 16); OpenSegment(usableSegmentId); byte[] header = new byte[16]; byte[] tmp = BitConverter.GetBytes(key1); Array.Copy(tmp, 0, header, 0, 4); tmp = BitConverter.GetBytes(key2); Array.Copy(tmp, 0, header, 4, 4); tmp = BitConverter.GetBytes(key3); Array.Copy(tmp, 0, header, 8, 4); tmp = BitConverter.GetBytes(value.Length); Array.Copy(tmp, 0, header, 12, 4); currentSegmentStream.Position = currentSegmentStream.Length; currentSegmentStream.Write(header, 0, header.Length); int valueSegment = usableSegmentId; long valueOffset = currentSegmentStream.Length; int valueLength = value.Length; putCommand.Parameters["@key1"].Value = key1; putCommand.Parameters["@key2"].Value = key2; putCommand.Parameters["@key3"].Value = key3; putCommand.Parameters["@segment"].Value = valueSegment; putCommand.Parameters["@offset"].Value = valueOffset; putCommand.Parameters["@length"].Value = valueLength; currentSegmentStream.Position = currentSegmentStream.Length; currentSegmentStream.Write(value, 0, value.Length); currentSegmentStream.Flush(true); dedupTuples.Add(itemHash, new Tuple <int, long, int>(valueSegment, valueOffset, valueLength)); } else { Tuple <int, long, int> dedup = dedupTuples[itemHash]; putCommand.Parameters["@key1"].Value = key1; putCommand.Parameters["@key2"].Value = key2; putCommand.Parameters["@key3"].Value = key3; putCommand.Parameters["@segment"].Value = dedup.Item1; putCommand.Parameters["@offset"].Value = dedup.Item2; putCommand.Parameters["@length"].Value = dedup.Item3; if (dedup.Item3 > 0) { Console.WriteLine("Deduplicated {0},{1},{2} (segment={3},offset={4},size={5})", key1, key2, key3, dedup.Item1, dedup.Item2, dedup.Item3); } } if (transaction == null) { transaction = connection.BeginTransaction(); writtenSinceTransaction = 0; } putCommand.ExecuteNonQuery(); writtenSinceTransaction += value.Length; if (writtenSinceTransaction > 10000000) { Flush(); } }