public static long Decompress(byte[] inputBuffer, byte[] outputBuffer) { var result = 0; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { result = CompressionSettings.Get().UseOodle ? OodleLib.OodleLZ_Decompress(inputBuffer, outputBuffer) : KrakenNative.Decompress(inputBuffer, outputBuffer); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { result = KrakenNative.Decompress(inputBuffer, outputBuffer); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { result = OozNative.Kraken_Decompress(inputBuffer, outputBuffer); } else { throw new NotImplementedException(); } return(result); }
public void CompareMemorySAsciiString() { //float result = 1; //for (int i = 2; i < 10; i++) //{ // if (i % 2 == 0) // { // result *= i; // } // else // { // result /= i; // } //} List <string> originals = new(); Dictionary <ulong, SAsciiString> hashDictionary = new(); hashDictionary.EnsureCapacity(500_000); var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"); var paths = new List <string>(runtimeAssemblies); var resolver = new PathAssemblyResolver(paths); var mlc = new MetadataLoadContext(resolver); var before = GC.GetTotalMemory(true); Assembly assembly; using (mlc) { assembly = mlc.LoadFromAssemblyPath("WolvenKit.Common.dll"); using var stream = assembly.GetManifestResourceStream(s_used); // read KARK header var oodleCompression = stream.ReadStruct <uint>(); if (oodleCompression != OodleHelper.KARK) { throw new DecompressionException($"Incorrect hash file."); } var outputsize = stream.ReadStruct <uint>(); // read the rest of the stream var outputbuffer = new byte[outputsize]; var inbuffer = stream.ToByteArray(true); OozNative.Kraken_Decompress(inbuffer, inbuffer.Length, outputbuffer, outputbuffer.Length); using (var ms = new MemoryStream(outputbuffer)) using (var sr = new StreamReader(ms)) { string line; while ((line = sr.ReadLine()) != null) { var hash = FNV1A64HashAlgorithm.HashString(line); if (hashDictionary.ContainsKey(hash)) { continue; } hashDictionary.Add(hash, new SAsciiString(line)); } } } var after = GC.GetTotalMemory(true); double diff = after - before; Console.WriteLine($"Memory: {diff.ToString()}"); // compare var failed = 0; foreach (var s in originals) { var hash = FNV1A64HashAlgorithm.HashString(s); var gottenString = hashDictionary[hash].ToString(); if (!gottenString.Equals(s)) { failed++; } } Assert.AreEqual(0, failed); }
public void CompareMemorySAsciiStringChunked() { List <string> originals = new(); Dictionary <ulong, uint[]> hashDictionary = new(); Dictionary <SAsciiString, uint> helperDict = new(new MyComparer()); hashDictionary.EnsureCapacity(500_000); var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"); var paths = new List <string>(runtimeAssemblies); var resolver = new PathAssemblyResolver(paths); var mlc = new MetadataLoadContext(resolver); var before = GC.GetTotalMemory(true); Assembly assembly; using (mlc) { assembly = mlc.LoadFromAssemblyPath("WolvenKit.Common.dll"); using var stream = assembly.GetManifestResourceStream(s_used); // read KARK header var oodleCompression = stream.ReadStruct <uint>(); if (oodleCompression != OodleHelper.KARK) { throw new DecompressionException($"Incorrect hash file."); } var outputsize = stream.ReadStruct <uint>(); // read the rest of the stream var outputbuffer = new byte[outputsize]; var inbuffer = stream.ToByteArray(true); OozNative.Kraken_Decompress(inbuffer, inbuffer.Length, outputbuffer, outputbuffer.Length); using (var ms = new MemoryStream(outputbuffer)) using (var sr = new StreamReader(ms)) { string line; while ((line = sr.ReadLine()) != null) { originals.Add(line); var hash = FNV1A64HashAlgorithm.HashString(line); var pathParts = line.Split('\\'); hashDictionary.Add(hash, new uint[pathParts.Length]); for (var i = 0; i < pathParts.Length; i++) { var s = pathParts[i]; var a = new SAsciiString(s); uint idx; if (helperDict.ContainsKey(a)) { idx = helperDict[a]; } else { //chunks.Add(a); var count = helperDict.Count; helperDict.Add(a, (uint)count); idx = (uint)count; } hashDictionary[hash][i] = idx; } } } } var after = GC.GetTotalMemory(true); double diff = after - before; Console.WriteLine($"Memory: {diff.ToString()}"); // compare var failed = 0; var keys = helperDict.Keys.ToList(); foreach (var s in originals) { var hash = FNV1A64HashAlgorithm.HashString(s); var gottenString = ""; for (var i = 0; i < hashDictionary[hash].Length; i++) { var idx = hashDictionary[hash][i]; gottenString += keys[(int)idx].ToString(); if (i < hashDictionary[hash].Length - 1) { gottenString += Path.DirectorySeparatorChar; } } if (!gottenString.Equals(s)) { failed++; } } Assert.AreEqual(0, failed); }
public static int Compress(byte[] inputBuffer, ref IEnumerable <byte> outputBuffer, bool useRedHeader, CompressionLevel level = CompressionLevel.Normal, Compressor compressor = Compressor.Kraken) { if (inputBuffer == null) { throw new ArgumentNullException(nameof(inputBuffer)); } var inputCount = inputBuffer.Length; if (inputCount <= 0 || inputCount > inputBuffer.Length) { throw new ArgumentOutOfRangeException(nameof(inputCount)); } if (outputBuffer == null) { throw new ArgumentNullException(nameof(outputBuffer)); } var result = 0; var compressedBufferSizeNeeded = Oodle.GetCompressedBufferSizeNeeded(inputCount); var compressedBuffer = new byte[compressedBufferSizeNeeded]; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { result = CompressionSettings.Get().UseOodle ? OodleLib.OodleLZ_Compress(inputBuffer, compressedBuffer, compressor, level) : KrakenNative.Compress(inputBuffer, compressedBuffer, (int)level); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { result = KrakenNative.Compress(inputBuffer, compressedBuffer, (int)level); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { result = OozNative.Kraken_Compress(inputBuffer, compressedBuffer, (int)level); } else { throw new NotImplementedException(); } if (result == 0 || inputCount <= (result + 8)) { outputBuffer = inputBuffer; return(outputBuffer.Count()); } if (useRedHeader) { // write KARK header var writelist = new List <byte>() { 0x4B, 0x41, 0x52, 0x4B //KARK, TODO: make this dependent on the compression algo }; // write size writelist.AddRange(BitConverter.GetBytes(inputCount)); // write compressed data writelist.AddRange(compressedBuffer.Take(result)); outputBuffer = writelist; } else { outputBuffer = compressedBuffer.Take(result); } return(outputBuffer.Count()); }