예제 #1
0
        static Global()
        {
            using (var mut = new CustomMutex(100))
            {
                MMFile = MemoryMappedFile.CreateOrOpen("LSharpShared", MemoryCapacity);
            }

            if (Common.isInitialized == false)
            {
                Common.InitializeCommonLib();
            }
        }
예제 #2
0
 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);
             }
         }
     }
 }
예제 #3
0
        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));
                }
            }
        }
예제 #4
0
        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);
                }
            }
        }
예제 #5
0
        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);
        }