static Global() { using (var mut = new CustomMutex(100)) { MMFile = MemoryMappedFile.CreateOrOpen("LSharpShared", MemoryCapacity); } if (Common.isInitialized == false) { Common.InitializeCommonLib(); } }
public static int Save(string path, string[] keys) { using (var mut = new CustomMutex(1200)) { using (var strm = MMFile.CreateViewAccessor()) { using (var fl = new System.IO.BinaryWriter(System.IO.File.Create(path))) { var signature = strm.ReadInt32(0); var startingOffset = 2 * sizeof(int); int currentOffset; if (signature == 0x34CFABC0) { currentOffset = strm.ReadInt32(sizeof(int)); } else { strm.Write(0, 0x34CFABC0); strm.Write(sizeof(int), startingOffset); currentOffset = startingOffset; } var thisOffset = startingOffset; OffsetEntry entry; var count = 0; while (thisOffset != currentOffset) { var buff = new byte[OffsetEntrySize]; strm.ReadArray(thisOffset, buff, 0, OffsetEntrySize); entry = FromByteArray <OffsetEntry>(buff); foreach (var key in keys) { var hash = CalculateHash(key); if (entry.Type != EntryType.Invalid && entry.KeyHash == hash) { fl.Write(buff); var buff2 = new byte[entry.Capacity]; strm.ReadArray(thisOffset + OffsetEntrySize, buff2, 0, entry.Capacity); fl.Write(buff2); count++; } } thisOffset += OffsetEntrySize + entry.Capacity; } return(count); } } } }
public static T Read <T>(string key, bool defaultIfMissing = false) { using (var mut = new CustomMutex(350)) { using (var strm = MMFile.CreateViewAccessor()) { var hash = CalculateHash(key); var signature = strm.ReadInt32(0); var startingOffset = 2 * sizeof(int); int currentOffset; if (signature == 0x34CFABC0) { currentOffset = strm.ReadInt32(sizeof(int)); } else { strm.Write(0, 0x34CFABC0); strm.Write(sizeof(int), startingOffset); currentOffset = startingOffset; } var thisOffset = startingOffset; OffsetEntry entry; while (thisOffset != currentOffset) { var buff = new byte[OffsetEntrySize]; strm.ReadArray(thisOffset, buff, 0, OffsetEntrySize); entry = FromByteArray <OffsetEntry>(buff); if (entry.Type != EntryType.Invalid && entry.KeyHash == hash) { if (typeof(T).IsValueType) { var buff2 = new byte[Marshal.SizeOf(typeof(T))]; strm.ReadArray(thisOffset + OffsetEntrySize, buff2, 0, Marshal.SizeOf(typeof(T))); return(FromByteArray <T>(buff2)); } else { byte[] buff2; if (typeof(T) == typeof(string)) { buff2 = new byte[entry.Capacity]; strm.ReadArray(thisOffset + OffsetEntrySize, buff2, 0, entry.Capacity); var data = System.Text.Encoding.UTF8.GetString(buff2, 0, entry.Capacity); var end = data.IndexOf('\0'); var result = data.Substring(0, end); return((T)(object)result); } if (typeof(T).IsSerializable) { var size = strm.ReadInt32(thisOffset + OffsetEntrySize); buff2 = new byte[size]; strm.ReadArray(thisOffset + OffsetEntrySize + sizeof(int), buff2, 0, size); // it is a class, must serialize. return(Deserialize <T>(buff2)); } throw new Exception( String.Format("Type {0} is not serializable! Cannot read.", typeof(T))); } } thisOffset += OffsetEntrySize + entry.Capacity; } if (!defaultIfMissing) { throw new Exception(String.Format("Config key '{0}' not found!", key)); } return(default(T)); } } }
public static void Write <T>(string key, T val) { using (var mut = new CustomMutex(700)) { using (var strm = MMFile.CreateViewAccessor()) { var hash = CalculateHash(key); var requiredCapacity = 8; byte[] serialized = null; if (typeof(T).IsValueType) { requiredCapacity = Marshal.SizeOf(typeof(T)); } else if (typeof(T) == typeof(string)) { requiredCapacity = val.ToString().Length + 1; } else if (typeof(T).IsSerializable) { // also store the sizeof the serialized object as what's ref'd by ptr serialized = Serialize(val); requiredCapacity = serialized.Length + sizeof(int); } else { throw new Exception(String.Format("Type {0} is not serializable! Cannot write.", typeof(T))); } var signature = strm.ReadInt32(0); var startingOffset = 2 * sizeof(int); int currentOffset; if (signature == 0x34CFABC0) { currentOffset = strm.ReadInt32(sizeof(int)); } else { strm.Write(0, 0x34CFABC0); strm.Write(sizeof(int), startingOffset); currentOffset = startingOffset; } var thisOffset = startingOffset; OffsetEntry entry; while (thisOffset != currentOffset) { var buff = new byte[OffsetEntrySize]; strm.ReadArray(thisOffset, buff, 0, OffsetEntrySize); entry = FromByteArray <OffsetEntry>(buff); if (entry.Type != EntryType.Invalid && entry.KeyHash == hash) { if (requiredCapacity <= entry.Capacity) { if (typeof(T).IsValueType) { var tobewritten = ToByteArray(val, entry.Capacity); strm.WriteArray( thisOffset + OffsetEntrySize, tobewritten, 0, buff.Length <= entry.Capacity ? buff.Length : entry.Capacity); } else if (typeof(T) != typeof(string)) { strm.WriteArray( thisOffset + OffsetEntrySize, ToByteArray(serialized.Length, sizeof(int)), 0, sizeof(int)); strm.WriteArray( thisOffset + OffsetEntrySize + sizeof(int), serialized, 0, serialized.Length); } else { var strz = System.Text.Encoding.UTF8.GetBytes(val + "\0"); strm.WriteArray(thisOffset + OffsetEntrySize, strz, 0, strz.Length); } return; } var overwriteEntry = entry; entry.Type = EntryType.Invalid; strm.WriteArray( thisOffset, ToByteArray(overwriteEntry, OffsetEntrySize), 0, OffsetEntrySize); } thisOffset += OffsetEntrySize + entry.Capacity; } OffsetEntry newEntry; newEntry.KeyHash = hash; newEntry.Capacity = (typeof(T).IsValueType ? 1 : 2) * requiredCapacity; newEntry.Type = EntryType.Basic; strm.WriteArray(currentOffset, ToByteArray(newEntry, OffsetEntrySize), 0, OffsetEntrySize); if (typeof(T).IsValueType) { var buffr = ToByteArray(val, newEntry.Capacity); strm.WriteArray( currentOffset + OffsetEntrySize, buffr, 0, buffr.Length <= newEntry.Capacity ? buffr.Length : newEntry.Capacity); } else if (typeof(T) != typeof(string)) { strm.WriteArray( thisOffset + OffsetEntrySize, ToByteArray(serialized.Length, sizeof(int)), 0, sizeof(int)); strm.WriteArray(thisOffset + OffsetEntrySize + sizeof(int), serialized, 0, serialized.Length); } else { var arr = System.Text.Encoding.UTF8.GetBytes(val + "\0"); strm.WriteArray(currentOffset + OffsetEntrySize, arr, 0, arr.Length); } // write new currentoffset strm.Write(sizeof(int), currentOffset + OffsetEntrySize + newEntry.Capacity); } } }
public static int Load(string path) { var LoadedEntries = new Dictionary <ulong, byte[]>(); var count = 0; using (var fl = new System.IO.BinaryReader(System.IO.File.Open(path, System.IO.FileMode.Open))) { long pos = 0; var len = fl.BaseStream.Length; while (pos != len) { var thisEntry = FromByteArray <OffsetEntry>(fl.ReadBytes(OffsetEntrySize)); LoadedEntries[thisEntry.KeyHash] = fl.ReadBytes(thisEntry.Capacity); pos += OffsetEntrySize + thisEntry.Capacity; count++; } } using (var mut = new CustomMutex(650)) { using (var strm = MMFile.CreateViewAccessor()) { var signature = strm.ReadInt32(0); var startingOffset = 2 * sizeof(int); int currentOffset; if (signature == 0x34CFABC0) { currentOffset = strm.ReadInt32(sizeof(int)); } else { strm.Write(0, 0x34CFABC0); strm.Write(sizeof(int), startingOffset); currentOffset = startingOffset; } var thisOffset = startingOffset; OffsetEntry entry; while (thisOffset != currentOffset) { var buff = new byte[OffsetEntrySize]; strm.ReadArray(thisOffset, buff, 0, OffsetEntrySize); entry = FromByteArray <OffsetEntry>(buff); if (entry.Type != EntryType.Invalid && LoadedEntries.ContainsKey(entry.KeyHash)) { if (LoadedEntries[entry.KeyHash].Length <= entry.Capacity) { strm.WriteArray( thisOffset + OffsetEntrySize, LoadedEntries[entry.KeyHash], 0, LoadedEntries[entry.KeyHash].Length <= entry.Capacity ? LoadedEntries[entry.KeyHash].Length : entry.Capacity); LoadedEntries.Remove(entry.KeyHash); } else { var overwriteEntry = entry; entry.Type = EntryType.Invalid; strm.WriteArray( thisOffset, ToByteArray(overwriteEntry, OffsetEntrySize), 0, OffsetEntrySize); } } thisOffset += OffsetEntrySize + entry.Capacity; } foreach (var needtoload in LoadedEntries) { OffsetEntry newEntry; newEntry.KeyHash = needtoload.Key; newEntry.Capacity = needtoload.Value.Length; newEntry.Type = EntryType.Basic; strm.WriteArray(currentOffset, ToByteArray(newEntry, OffsetEntrySize), 0, OffsetEntrySize); strm.WriteArray(currentOffset + OffsetEntrySize, needtoload.Value, 0, newEntry.Capacity); strm.Write(sizeof(int), currentOffset + OffsetEntrySize + newEntry.Capacity); } } } return(count); }