public void Precache <T> (GroupInfo info) where T : new()
        {
            return;

            if (info == null)
            {
                info = GetGroupInfo <T> ();
            }
            var type  = typeof(T);
            var tuple = new Tuple <Type, string> (type, info.ToString());

            FillGroups(type, info);
            using (ThreadLock.Lock(groupLocker)) {
                if (Groups [tuple].Count() == 0)
                {
                    SetGroups(type, info);
                }

                foreach (var group in Groups[tuple])
                {
                    if (group.Loaded)
                    {
                        continue;
                    }
                    cacheQueue.AddLast(delegate {
                        LoadItemsForGroup <T> (group);
                    });
                }
            }
            StartQueue();
        }
        private InstantDatabaseGroup GetGroup(Type t, GroupInfo info, int section)
        {
            var tuple = new Tuple <Type, string> (t, info.ToString());
            List <InstantDatabaseGroup> group = null;
            int count = 0;

            while ((group == null || group.Count <= section) && count < 5)
            {
                if (count > 0)
                {
                    Console.WriteLine("Trying to fill groups: {0}", count);
                }
                using (ThreadLock.Lock(groupLocker)){
                    Groups.TryGetValue(tuple, out group);
                }
                if (group == null)
                {
                    FillGroups(t, info);
                }

                count++;
            }
            if (group == null || group.Count == 0)
            {
                return(new InstantDatabaseGroup());
            }
            return(group [section]);
        }
 public void AddObjectToDict(object item, Type t)
 {
     using (ThreadLock.Lock(groupLocker))
     {
         var primaryKey = GetPrimaryKeyProperty(t);
         if (primaryKey == null)
         {
             return;
         }
         object pk = primaryKey.GetValue(item, null);
         if (!ObjectsDict.ContainsKey(t))
         {
             ObjectsDict.Add(t, new Dictionary <object, object>());
         }
         if (ObjectsDict[t].ContainsKey(pk))
         {
             ObjectsDict[t][pk] = item;
         }
         else
         {
             ObjectsDict[t].Add(pk, item);
         }
         //				if (!Objects.ContainsKey (t))
         //					Objects.Add (t, new List<object> ());
         //				if (!Objects [t].Contains (item))
         //					Objects [t].Add (item);
     }
 }
        public T ObjectForRow <T> (GroupInfo info, int section, int row) where T : new()
        {
            if (info == null)
            {
                info = GetGroupInfo <T> ();
            }
            using (ThreadLock.Lock(memStoreLocker)) {
                var type  = typeof(T);
                var tuple = new Tuple <Type, string> (type, info.ToString());
                if (MemoryStore.ContainsKey(tuple))
                {
                    var groups = MemoryStore [tuple];
                    if (groups.ContainsKey(section))
                    {
                        var g = groups [section];
                        if (g.ContainsKey(row))
                        {
                            return((T)groups [section] [row]);
                        }
                    }
                }

                Precache <T> (info, section);
                return(getObject <T> (info, section, row));
            }
        }
        public void ClearMemory(Type type, GroupInfo groupInfo)
        {
            var tuple = new Tuple <Type, string> (type, groupInfo.ToString());

            using (ThreadLock.Lock(memStoreLocker)){
                MemoryStore.Remove(tuple);
            }
            Groups.Clear();
        }
 public void ClearMemory()
 {
     using (ThreadLock.Lock(memStoreLocker)) {
         ObjectsDict.Clear();
         ClearMemoryStore();
         //Objects.Clear ();
         //GC.Collect ();
     }
 }
 public void ClearMemoryStore()
 {
     using (ThreadLock.Lock(memStoreLocker)) {
         MemoryStore.Clear();
         using (ThreadLock.Lock(groupLocker)){
             Groups.Clear();
             GroupInfoDict.Clear();
         }
     }
 }
 public int RowsInSection <T> (GroupInfo info, int section)
 {
     if (info == null)
     {
         info = GetGroupInfo <T> ();
     }
     using (ThreadLock.Lock(groupLocker)) {
         var group = GetGroup <T> (info, section);
         return(group.RowCount);
     }
 }
        private T getObject <T> (GroupInfo info, int section, int row) where T : new()
        {
            try{
                T   item;
                var t     = typeof(T);
                var group = GetGroup <T> (info, section);

                string query;
                if (string.IsNullOrEmpty(info.GroupBy))
                {
                    query = string.Format("select * from {0} {1} {2} LIMIT {3}, 1", info.FromString(t.Name), info.FilterString(true), info.OrderByString(true), row);
                }
                else
                {
                    query = string.Format("select * from {0} where {1} = ? {3} {2} LIMIT ? , 1", info.FromString(t.Name), info.GroupBy, info.OrderByString(true), info.FilterString(false));
                }


                item = connection.Query <T> (query, group.GroupString, row).FirstOrDefault();

                if (item == null)
                {
                    return(new T());
                }
                var tuple = new Tuple <Type, string> (t, info.ToString());
                using (ThreadLock.Lock(memStoreLocker)) {
                    if (!MemoryStore.ContainsKey(tuple))
                    {
                        MemoryStore.Add(tuple, new Dictionary <int, Dictionary <int, object> > ());
                    }
                    var groups = MemoryStore [tuple];
                    if (!groups.ContainsKey(section))
                    {
                        groups.Add(section, new Dictionary <int, object> ());
                    }
                    if (!groups [section].ContainsKey(row))
                    {
                        groups [section].Add(row, item);
                    }
                    else
                    {
                        groups [section] [row] = item;
                    }
                    AddObjectToDict(item);
                    return(item);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(default(T));
            }
        }
 public int NumberOfSections <T> (GroupInfo info)
 {
     if (info == null)
     {
         info = GetGroupInfo <T> ();
     }
     using (ThreadLock.Lock(groupLocker)) {
         var t     = typeof(T);
         var tuple = new Tuple <Type, string> (t, info.ToString());
         if (!Groups.ContainsKey(tuple))
         {
             FillGroups(t, info);
         }
         return(Groups [tuple].Count);
     }
 }
        public void UpdateInstant(Type type, GroupInfo info)
        {
            if (info == null)
            {
                info = GetGroupInfo(type);
            }
            var tuple = new Tuple <Type, string> (type, info.ToString());

            using (ThreadLock.Lock(memStoreLocker)) {
                if (MemoryStore.ContainsKey(tuple))
                {
                    MemoryStore [tuple] = new Dictionary <int, Dictionary <int, object> > ();
                }
            }
            FillGroups(type, info);
        }
        private void FillGroups(Type t, GroupInfo info)
        {
            List <InstantDatabaseGroup> groups;

            groups = CreateGroupInfo(t, info);
            using (ThreadLock.Lock(groupLocker)) {
                var tuple = new Tuple <Type, string> (t, info.ToString());
                if (!Groups.ContainsKey(tuple))
                {
                    Groups.Add(tuple, groups);
                }
                else
                {
                    Groups [tuple] = groups;
                }
            }
        }
 public string [] QuickJump <T> (GroupInfo info)
 {
     if (info == null)
     {
         info = GetGroupInfo <T> ();
     }
     using (ThreadLock.Lock(groupLocker)) {
         var t     = typeof(T);
         var tuple = new Tuple <Type, string> (t, info.ToString());
         if (!Groups.ContainsKey(tuple))
         {
             FillGroups(t, info);
         }
         var groups  = Groups [tuple];
         var strings = groups.Select(x => string.IsNullOrEmpty(x.GroupString) ? "" : x.GroupString [0].ToString()).ToArray();
         return(strings);
     }
 }
        public string SectionHeader <T> (GroupInfo info, int section)
        {
            if (info == null)
            {
                info = GetGroupInfo <T> ();
            }

            using (ThreadLock.Lock(groupLocker)) {
                var t     = typeof(T);
                var tuple = new Tuple <Type, string> (t, info.ToString());
                if (!Groups.ContainsKey(tuple) || Groups [tuple].Count <= section)
                {
                    FillGroups(t, info);
                }
                try{
                    return(Groups [tuple] [section].GroupString);
                }
                catch (Exception ex)
                {
                    return("");
                }
            }
        }
        private void LoadItemsForGroup <T> (InstantDatabaseGroup group) where T : new()
        {
            try{
                if (group.Loaded)
                {
                    return;
                }
                Console.WriteLine("Loading items for group");
                var      type  = typeof(T);
                string   query = string.Format("select * from {0} where {1} = ? {3} {2} LIMIT ? , 50", group.FromString(type.Name), group.GroupBy, group.OrderByString(true), group.FilterString(false));
                List <T> items;
                int      current = 0;
                bool     hasMore = true;
                while (hasMore)
                {
                    if (string.IsNullOrEmpty(group.GroupBy))
                    {
                        query = string.Format("select * from {0} {1} {2} LIMIT {3}, 50", group.FromString(type.Name), group.FilterString(true), group.OrderByString(true), current);
                    }

                    items = connection.Query <T> (query, group.GroupString, current).ToList();

                    {
                        Dictionary <int, object> memoryGroup;
                        using (ThreadLock.Lock(memStoreLocker)){
                            var tuple = new Tuple <Type, string> (type, group.ToString());
                            if (!MemoryStore.ContainsKey(tuple))
                            {
                                MemoryStore.Add(tuple, new Dictionary <int, Dictionary <int, object> > ());
                            }

                            if (!MemoryStore [tuple].ContainsKey(group.Order))
                            {
                                try{
                                    MemoryStore [tuple].Add(group.Order, new Dictionary <int, object> ());
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex);
                                }
                            }
                            memoryGroup = MemoryStore [tuple] [group.Order];
                        }
                        for (int i = 0; i < items.Count; i++)
                        {
                            lock (groupLocker)
                            {
                                if (memoryGroup.ContainsKey(i + current))
                                {
                                    memoryGroup [i + current] = items [i];
                                }
                                else
                                {
                                    memoryGroup.Add(i + current, items [i]);
                                }
                            }
                            AddObjectToDict(items [i]);
                        }
                    }
                    current += items.Count;
                    if (current == group.RowCount)
                    {
                        hasMore = false;
                    }
                }
                Console.WriteLine("group loaded");
                group.Loaded = true;
            }
            catch (Exception ex) {
                Console.WriteLine(ex);
            }
        }