Ejemplo n.º 1
0
        public IEnumerable <T> Find <T>(string tablename, string key) where T : new()
        {
            string          tablefile = GetTableFile(tablename);
            EntityTableMeta meta      = GetMetaData(tablename);
            Dictionary <long, EntityTableIndexItem> arr = null;
            EntityTableIndexItem indexitem = null;

            if (keyindexdic[tablename].TryGetValue(key, out arr))
            {
                //先找到offset
                using (ObjTextReader otw = ObjTextReader.CreateReader(tablefile))
                {
                    foreach (var o in arr)
                    {
                        indexitem = (EntityTableIndexItem)o.Value;
                        if (!indexitem.Del)
                        {
                            otw.SetPostion(indexitem.Offset);

                            var readobj = otw.ReadObject <EntityTableItem <T> >();
                            if (readobj == null)
                            {
                                yield return(default(T));
                            }
                            else
                            {
                                yield return(readobj.Data);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private void LoadKey(string tablename, EntityTableMeta meta)
        {
            string indexfile      = GetKeyFile(tablename);
            var    indexmergeinfo = meta.IndexMergeInfos.Find(p => p.IndexName.Equals(meta.KeyName));

            if (indexmergeinfo == null)
            {
                indexmergeinfo           = new IndexMergeInfo();
                indexmergeinfo.IndexName = meta.KeyName;
                meta.IndexMergeInfos.Add(indexmergeinfo);
            }
            using (ObjTextReader idx = ObjTextReader.CreateReader(indexfile))
            {
                if (indexmergeinfo.IndexMergePos > 0)
                {
                    idx.SetPostion(indexmergeinfo.IndexMergePos);
                }
                var idc = keyindexdic[tablename];
                Dictionary <long, EntityTableIndexItem> al = null;
                foreach (var newindex in idx.ReadObjectsWating <EntityTableIndexItem>(1))
                {
                    if (!idc.TryGetValue(newindex.Key, out al))
                    {
                        lock (idc)
                        {
                            if (!idc.TryGetValue(newindex.Key, out al))
                            {
                                al = new Dictionary <long, EntityTableIndexItem>();
                                idc.TryAdd(newindex.Key, al);
                            }
                        }
                    }

                    if (newindex.Del)
                    {
                        al.Remove(newindex.Offset);
                    }
                    else
                    {
                        lock (al)
                        {
                            al.Add(newindex.Offset, newindex);
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        private EntityTableIndexItemBag LoadIndex(string tablename, string indexname, EntityTableMeta meta)
        {
            string key = string.Format("{0}##{1}", tablename, indexname);
            EntityTableIndexItemBag temp = null;

            if (indexdic.TryGetValue(key, out temp))
            {
                temp.LastUsed = DateTime.Now;
            }

            string indexfile = GetIndexFile(tablename, indexname);
            var    locker    = GetKeyLocker(tablename, "index_" + indexname);

            lock (locker)
            {
                if (indexdic.TryGetValue(key, out temp))
                {
                    temp.LastUsed = DateTime.Now;
                }
                else
                {
                    temp = new EntityTableIndexItemBag();
                }

                using (ObjTextReader idxreader = ObjTextReader.CreateReader(indexfile))
                {
                    if (temp.LastOffset > 0)
                    {
                        idxreader.SetPostion(temp.LastOffset);
                    }

                    Dictionary <long, EntityTableIndexItem> al = null;
                    foreach (var newindex in idxreader.ReadObjectsWating <EntityTableIndexItem>(1))
                    {
                        temp.LastOffset = idxreader.ReadedPostion();
                        if (!temp.Dics.TryGetValue(newindex.Key, out al))
                        {
                            al = new Dictionary <long, EntityTableIndexItem>();
                            temp.Dics.TryAdd(newindex.Key, al);
                        }

                        if (newindex.Del)
                        {
                            al.Remove(newindex.Offset);
                        }
                        else
                        {
                            al.Add(newindex.Offset, newindex);
                        }
                    }
                }

                if (temp.LastUsed == DateTime.MinValue)
                {
                    temp.LastUsed = DateTime.Now;
                    indexdic.TryAdd(key, temp);
                    LJC.FrameWork.Comm.Coroutine.CoroutineEngine.DefaultCoroutineEngine.Dispatcher(new IndexDestroy(indexdic, key));
                }
                else
                {
                    temp.LastUsed = DateTime.Now;
                }
            }

            return(temp);
        }
        public void MergeKey2(string tablename, string indexname, BigEntityTableMeta meta)
        {
            ProcessTraceUtil.StartTrace();

            IndexMergeInfo mergeinfo = null;

            lock (meta)
            {
                mergeinfo = meta.IndexMergeInfos.Find(p => indexname.Equals(p.IndexName));
                if (mergeinfo == null)
                {
                    mergeinfo           = new IndexMergeInfo();
                    mergeinfo.IndexName = indexname;
                    meta.IndexMergeInfos.Add(mergeinfo);
                }

                if (mergeinfo.IsMergin)
                {
                    return;
                }
                meta.NewAddCount   = 0;
                mergeinfo.IsMergin = true;
            }
            DateTime timestart    = DateTime.Now;
            string   newindexfile = string.Empty;

            byte[] bigbuffer   = new byte[1024 * 1024];
            byte[] smallbuffer = new byte[2048];
            try
            {
                ProcessTraceUtil.TraceMem("开始整理key:" + indexname, "m");

                long   lasmargepos      = 0;
                long   newIndexMergePos = mergeinfo.IndexMergePos;
                string indexfile        = indexname.Equals(meta.KeyName) ? GetKeyFile(tablename) : GetIndexFile(tablename, indexname);
                var    tablelocker      = GetKeyLocker(tablename, string.Empty);

                //新的磁盘索引
                List <BigEntityTableIndexItem> newdiskindexlist = new List <BigEntityTableIndexItem>();
                var loadFactor = (int)Math.Max(4, new FileInfo(indexfile).Length / MAX_KEYBUFFER);

                using (var reader = ObjTextReader.CreateReader(indexfile))
                {
                    long readoldstartpostion = reader.ReadedPostion();

                    try
                    {
                        tablelocker.EnterWriteLock();
                        keyindexmemtemplist[tablename] = keyindexmemlist[tablename];
                        keyindexmemlist[tablename]     = new SortArrayList <BigEntityTableIndexItem>();
                    }
                    finally
                    {
                        tablelocker.ExitWriteLock();
                    }
                    var listtemp = keyindexmemtemplist[tablename].GetList().ToList();
                    listtemp = listtemp.Select(p => new BigEntityTableIndexItem
                    {
                        Del        = p.Del,
                        Key        = p.Key,
                        KeyOffset  = p.KeyOffset,
                        len        = p.len,
                        Offset     = p.Offset,
                        Index      = p.Index,
                        RangeIndex = p.RangeIndex
                    }).ToList();
                    int readcount = listtemp.Count;

                    ProcessTraceUtil.TraceMem("从内存中读取新增数据,共" + readcount + "条", "m");

                    if (readcount == 0)
                    {
                        return;
                    }

                    lasmargepos = listtemp.Max(p => p.KeyOffset);
                    reader.SetPostion(lasmargepos);
                    reader.ReadObject <BigEntityTableIndexItem>();
                    lasmargepos = reader.ReadedPostion();

                    //优化确定哪些部分是不需要一个个读入的
                    long copybefore = 0, copylast = 0;
                    long lastrankindex = 0;
                    var  indexarray    = keyindexdisklist[tablename];
                    using (var sortarray = new Collections.SorteArray <BigEntityTableIndexItem>(indexarray))
                    {
                        int mid = -1;
                        int pos = sortarray.Find(listtemp.First(), ref mid);
                        ProcessTraceUtil.Trace("查找新数据在老数中插入的开始位置:mid=" + mid + ",pos=" + pos);
                        if (pos == -1 && mid != -1)
                        {
                            //小于最小的
                            copybefore    = indexarray[mid].KeyOffset;
                            lastrankindex = indexarray[mid].RangeIndex;
                            ProcessTraceUtil.Trace("老数据可以直接copy的部分:0->" + copybefore);
                        }
                        else if (pos != -1)
                        {
                            copybefore    = indexarray[pos].KeyOffset;
                            lastrankindex = indexarray[pos].RangeIndex;
                            ProcessTraceUtil.Trace("老数据可以直接copy的部分:0->" + copybefore);
                        }

                        //优化确定后面读到哪

                        mid = -1;
                        pos = sortarray.Find(listtemp.Last(), ref mid);
                        ProcessTraceUtil.Trace("查找新数据在老数据中插入的结束位置:mid=" + mid + ",pos=" + pos);
                        if (pos == -1 && mid != -1 && mid < indexarray.Length - 1)
                        {
                            //小于最小的
                            copylast = indexarray[mid + 1].KeyOffset;
                            ProcessTraceUtil.Trace("老数据可以直接copy的部分:" + copylast + "->" + mergeinfo.IndexMergePos);
                        }
                        else if (pos != -1)
                        {
                            copylast = indexarray[pos].KeyOffset;
                            ProcessTraceUtil.Trace("老数据可以直接copy的部分:" + copylast + "->" + mergeinfo.IndexMergePos);
                        }
                    }

                    newindexfile = (indexname.Equals(meta.KeyName) ? GetKeyFile(tablename) : GetIndexFile(tablename, indexname)) + ".temp";
                    if (File.Exists(newindexfile))
                    {
                        File.Delete(newindexfile);
                    }
                    //快速copy
                    if (copybefore > 0)
                    {
                        ProcessTraceUtil.TraceMem("直接copy前面不在排序范围的数据:0->" + copybefore, "m");
                        IOUtil.CopyFile(indexfile, newindexfile, FileMode.Create, 0, copybefore - 1);
                        readoldstartpostion = copybefore;
                        ProcessTraceUtil.TraceMem("copy数据完成", "m");

                        newdiskindexlist.AddRange(keyindexdisklist[tablename].Where(p => p.KeyOffset < copybefore));
                    }

                    bool isall = false;
                    ProcessTraceUtil.TraceMem("开始读取在排序范围内的数据", "m");
                    while (true)
                    {
                        ProcessTraceUtil.Trace("读取老数据,开始位置:" + readoldstartpostion);
                        reader.SetPostion(readoldstartpostion);
                        var  listordered = new List <BigEntityTableIndexItem>();
                        var  loadcount   = 0;
                        long keyoffset   = 0;
                        foreach (var item in reader.ReadObjectsWating <BigEntityTableIndexItem>(1, p => keyoffset = p, bigbuffer))
                        {
                            item.KeyOffset = keyoffset;
                            item.SetIndex(meta.KeyIndexInfo);

                            if (item.KeyOffset >= mergeinfo.IndexMergePos)
                            {
                                break;
                            }
                            if (copylast > 0 && item.KeyOffset >= copylast)
                            {
                                break;
                            }
                            listordered.Add(item);
                            if (++loadcount >= MERGE_TRIGGER_NEW_COUNT)
                            {
                                break;
                            }
                        }

                        readoldstartpostion = reader.ReadedPostion();
                        bool isonlyoldlist = false;

                        if (listordered.Count == 0)
                        {
                            ProcessTraceUtil.TraceMem("老数据没有了,全部是新数据:" + listtemp.Count, "m");

                            listordered = MergeAndSort2(listordered, listtemp).ToList();
                            foreach (var item in listordered)
                            {
                                item.RangeIndex = lastrankindex++;
                            }
                            isall = true;
                        }
                        else if (listtemp.Count == 0 && listordered.Count > 10000)
                        {
                            ProcessTraceUtil.TraceMem("新数据没有了,全部是老数据:" + listordered.Count, "m");
                            //copy
                            IOUtil.CopyFile(indexfile, newindexfile, FileMode.Open, listordered.First().KeyOffset, listordered.Last().KeyOffset - 1, false);
                            var  listorderedlast = listordered.Last();
                            long copyoffset      = 0;
                            using (var nw = ObjTextWriter.CreateWriter(newindexfile, ObjTextReaderWriterEncodeType.entitybuf2))
                            {
                                var item = new BigEntityTableIndexItem {
                                    Del = listorderedlast.Del, Key = listorderedlast.Key, len = listorderedlast.len, Offset = listorderedlast.Offset, Index = listorderedlast.Index
                                };
                                item.KeyOffset = nw.GetWritePosition();

                                copyoffset = nw.GetWritePosition() - listorderedlast.KeyOffset;

                                nw.AppendObject(item);
                                newIndexMergePos = nw.GetWritePosition();
                            }
                            isonlyoldlist = true;
                            //更新索引
                            foreach (var item in listordered)
                            {
                                item.RangeIndex = lastrankindex++;
                                item.KeyOffset += copyoffset;
                            }

                            ProcessTraceUtil.TraceMem("直接copy数据完成", "m");
                        }
                        else
                        {
                            ProcessTraceUtil.TraceMem("老数据条数为:" + listordered.Count + ",新数据条数为:" + listtemp.Count, "m");

                            var listordermax = listordered.Last();

                            int idx = 0;
                            foreach (var item in listtemp)
                            {
                                if (item.CompareTo(listordermax) > 0)
                                {
                                    break;
                                }
                                else
                                {
                                    idx++;
                                }
                            }
                            List <BigEntityTableIndexItem> smalllist = listtemp.Take(idx).ToList();
                            listtemp    = listtemp.Skip(idx).ToList();
                            listordered = MergeAndSort2(listordered, smalllist).ToList();
                            foreach (var item in listordered)
                            {
                                item.RangeIndex = lastrankindex++;

                                //ProcessTraceUtil.Trace("rangeindex:" + item.Key[0] + "->" + (item.RangeIndex));
                            }
                            ProcessTraceUtil.TraceMem("排序完成:" + listordered.Count + "条", "m");
                        }

                        if (listordered.Count > 0)
                        {
                            if (!isonlyoldlist)
                            {
                                ProcessTraceUtil.TraceMem("把排好的数据写入到新索引文件:" + listordered.Count + "条", "m");
                                using (var nw = ObjTextWriter.CreateWriter(newindexfile, ObjTextReaderWriterEncodeType.entitybuf2))
                                {
                                    foreach (var item in listordered)
                                    {
                                        item.KeyOffset = nw.GetWritePosition();
                                        nw.AppendObject(item);
                                    }
                                    newIndexMergePos = nw.GetWritePosition();
                                }
                                ProcessTraceUtil.TraceMem("写入到新索引文件完成", "m");
                            }

                            if (listordered.Count <= 2 || loadFactor == 1)
                            {
                                newdiskindexlist.AddRange(listordered);
                            }
                            else
                            {
                                newdiskindexlist.Add(listordered.First());
                                int idx = 0;
                                foreach (var item in listordered)
                                {
                                    if ((++idx) % loadFactor == 0)
                                    {
                                        newdiskindexlist.Add(item);
                                    }
                                }
                                //newdiskindexlist.AddRange(listordered.Where(p => (++idx) % loadFactor == 0));
                                if (idx % loadFactor != 0)
                                {
                                    newdiskindexlist.Add(listordered.Last());
                                }
                            }
                        }

                        ProcessTraceUtil.TraceMem("写入到新索引文件后整理索引完成", "m");

                        if (isall)
                        {
                            if (copylast > 0 && copylast < mergeinfo.IndexMergePos)
                            {
                                ProcessTraceUtil.TraceMem("copy已排序的大于新增最大数部分" + copylast + "->" + mergeinfo.IndexMergePos, "m");
                                var offset = 0L;
                                using (var nw = ObjTextWriter.CreateWriter(newindexfile, ObjTextReaderWriterEncodeType.entitybuf2))
                                {
                                    offset = nw.GetWritePosition() - copylast;
                                }
                                //copy
                                long newindexpos = IOUtil.CopyFile(indexfile, newindexfile, FileMode.Open, copylast, mergeinfo.IndexMergePos - 1, false);

                                foreach (var p in keyindexdisklist[tablename])
                                {
                                    if (p.KeyOffset >= copylast && p.KeyOffset < mergeinfo.IndexMergePos)
                                    {
                                        newdiskindexlist.Add(new BigEntityTableIndexItem
                                        {
                                            Del        = p.Del,
                                            Key        = p.Key,
                                            KeyOffset  = p.KeyOffset + offset,
                                            len        = p.len,
                                            Offset     = p.Offset,
                                            Index      = p.Index,
                                            RangeIndex = p.RangeIndex + readcount
                                        });
                                    }
                                }

                                ProcessTraceUtil.TraceMem("copy数据完成->" + offset, "m");
                            }
                            break;
                        }
                        else
                        {
                            if (listtemp.Count > 0)
                            {
                                long newcopybefore = 0;
                                using (var sortarray = new Collections.SorteArray <BigEntityTableIndexItem>(indexarray))
                                {
                                    int mid = -1;
                                    int pos = sortarray.Find(listtemp.First(), ref mid);
                                    ProcessTraceUtil.Trace("查找已经排序的小于新增最小数据部分:mid=" + mid + ",pos=" + pos);
                                    if (pos == -1 && mid != -1)
                                    {
                                        //小于最小的
                                        newcopybefore = indexarray[mid].KeyOffset;
                                        lastrankindex = indexarray[mid].RangeIndex + readcount - listtemp.Count;
                                    }
                                    else if (pos != -1)
                                    {
                                        newcopybefore = indexarray[pos].KeyOffset;
                                        lastrankindex = indexarray[pos].RangeIndex + readcount - listtemp.Count;
                                    }
                                }
                                if (newcopybefore > readoldstartpostion)
                                {
                                    ProcessTraceUtil.Trace("中间copy");
                                    var offset = 0L;
                                    using (var nw = ObjTextWriter.CreateWriter(newindexfile, ObjTextReaderWriterEncodeType.entitybuf2))
                                    {
                                        offset = nw.GetWritePosition() - readoldstartpostion;
                                    }
                                    IOUtil.CopyFile(indexfile, newindexfile, FileMode.Open, readoldstartpostion, newcopybefore - 1, false);

                                    foreach (var p in keyindexdisklist[tablename])
                                    {
                                        if (p.KeyOffset >= readoldstartpostion && p.KeyOffset < newcopybefore)
                                        {
                                            newdiskindexlist.Add(new BigEntityTableIndexItem
                                            {
                                                Del        = p.Del,
                                                Key        = p.Key,
                                                KeyOffset  = p.KeyOffset + offset,
                                                len        = p.len,
                                                Offset     = p.Offset,
                                                Index      = p.Index,
                                                RangeIndex = p.RangeIndex + readcount - listtemp.Count
                                            });
                                        }
                                    }

                                    readoldstartpostion = newcopybefore;
                                    ProcessTraceUtil.Trace("中间copy完成");
                                }
                                else if (newcopybefore < readoldstartpostion)
                                {
                                    ProcessTraceUtil.Trace("补中间");
                                    reader.SetPostion(newcopybefore);
                                    //补充数目
                                    foreach (var item in reader.ReadObjectsWating <BigEntityTableIndexItem>(1, p => keyoffset = p, smallbuffer))
                                    {
                                        item.KeyOffset = keyoffset;
                                        item.SetIndex(meta.KeyIndexInfo);
                                        //ProcessTraceUtil.Trace(item.Key[0].ToString());
                                        if (item.KeyOffset >= mergeinfo.IndexMergePos)
                                        {
                                            break;
                                        }
                                        if (copylast > 0 && item.KeyOffset >= copylast)
                                        {
                                            break;
                                        }
                                        if (item.KeyOffset == readoldstartpostion)
                                        {
                                            break;
                                        }
                                        if (item.Del)
                                        {
                                            continue;
                                        }
                                        //ProcessTraceUtil.Trace("补中间+1");
                                        lastrankindex++;
                                    }
                                }
                            }
                            else
                            {
                                ProcessTraceUtil.Trace("中间copy2");
                                var offset = 0L;
                                using (var nw = ObjTextWriter.CreateWriter(newindexfile, ObjTextReaderWriterEncodeType.entitybuf2))
                                {
                                    offset = nw.GetWritePosition() - readoldstartpostion;
                                }
                                IOUtil.CopyFile(indexfile, newindexfile, FileMode.Open, readoldstartpostion, copylast - 1, false);

                                foreach (var p in keyindexdisklist[tablename])
                                {
                                    if (p.KeyOffset >= readoldstartpostion && p.KeyOffset < copylast)
                                    {
                                        newdiskindexlist.Add(new BigEntityTableIndexItem
                                        {
                                            Del        = p.Del,
                                            Key        = p.Key,
                                            KeyOffset  = p.KeyOffset + offset,
                                            len        = p.len,
                                            Offset     = p.Offset,
                                            Index      = p.Index,
                                            RangeIndex = p.RangeIndex + readcount
                                        });
                                    }
                                }

                                readoldstartpostion = copylast;
                                ProcessTraceUtil.Trace("中间copy2完成");
                            }
                        }
                    }
                }

                //后面copy
                string tablefile = GetTableFile(tablename);

                var idxreader = ObjTextReader.CreateReader(indexfile);
                var newwriter = ObjTextWriter.CreateWriter(newindexfile, ObjTextReaderWriterEncodeType.entitybuf2);
                try
                {
                    long nextcopypos = 0;
                    ProcessTraceUtil.TraceMem("读取后面的数据->" + lasmargepos, "m");
                    idxreader.SetPostion(lasmargepos);
                    bool hasitem   = false;
                    bool isfirst   = true;
                    long keyoffset = 0;
                    foreach (var item in idxreader.ReadObjectsWating <BigEntityTableIndexItem>(1, p => keyoffset = p, smallbuffer))
                    {
                        hasitem = true;
                        item.SetIndex(meta.KeyIndexInfo);
                        item.KeyOffset = keyoffset;
                        if (item.KeyOffset > newwriter.GetWritePosition())
                        {
                            var spacelen = item.KeyOffset - newwriter.GetWritePosition();
                            ProcessTraceUtil.Trace("没有对齐,尝试对齐,spacelen->" + spacelen);
                            if (spacelen % 3 == 0)
                            {
                                newwriter.FillSpace(spacelen / 3);
                            }
                            else
                            {
                                ProcessTraceUtil.Trace("对齐失败");
                                var ex = new Exception("无法对齐");
                                ex.Data.Add("老索引文件当前位置", item.KeyOffset);
                                ex.Data.Add("新索引文件写入位置", newwriter.GetWritePosition());
                                throw ex;
                            }
                        }

                        if (item.KeyOffset == newwriter.GetWritePosition())
                        {
                            nextcopypos = newwriter.GetWritePosition();
                            if (isfirst)
                            {
                                newIndexMergePos = nextcopypos;
                            }
                            ProcessTraceUtil.Trace("新老索引文件已经对齐:" + item.KeyOffset);
                            break;
                        }

                        isfirst        = false;
                        item.KeyOffset = newwriter.GetWritePosition();
                        newwriter.AppendObject(item);
                    }

                    if (nextcopypos > 0)
                    {
                        newwriter.Dispose();
                        ProcessTraceUtil.Trace("copy后面的数据->" + nextcopypos);
                        nextcopypos = IOUtil.CopyFile(indexfile, newindexfile, FileMode.Open, nextcopypos, -512);
                    }
                    else if (!hasitem)
                    {
                        var idxpos = idxreader.ReadedPostion();
                        if (idxpos == newwriter.GetWritePosition())
                        {
                            nextcopypos = idxpos;
                            newwriter.Dispose();
                        }
                        else
                        {
                            ProcessTraceUtil.Trace(idxpos + " vs " + newwriter.GetWritePosition());
                        }
                    }
                    ProcessTraceUtil.TraceMem("读取后面的数据完成", "m");
                    if (nextcopypos == 0)
                    {
                        throw new Exception("更新索引出错");
                    }

                    try
                    {
                        BigEntityTableIndexItem[] oldindexarray     = null;
                        BigEntityTableIndexItem[] newdiskindexarray = newdiskindexlist.ToArray();

                        tablelocker.EnterWriteLock();
                        ProcessTraceUtil.TraceMem("读取后面的数据->" + lasmargepos, "m");
                        if (nextcopypos <= 0)
                        {
                            using (newwriter)
                            {
                                using (idxreader)
                                {
                                    foreach (var item in idxreader.ReadObjectsWating <BigEntityTableIndexItem>(1, bytes: bigbuffer))
                                    {
                                        item.SetIndex(meta.KeyIndexInfo);
                                        item.KeyOffset = newwriter.GetWritePosition();
                                        newwriter.AppendObject(item);
                                    }
                                }
                            }
                        }
                        else
                        {
                            nextcopypos = IOUtil.CopyFile(indexfile, newindexfile, FileMode.Open, nextcopypos, long.MaxValue);
                            ProcessTraceUtil.TraceMem("继续copy后面的数据->" + nextcopypos, "m");
                            idxreader.Dispose();
                        }
                        ProcessTraceUtil.TraceMem("读取后面的数据完成", "m");

                        //更新索引
                        mergeinfo.LoadFactor = loadFactor;
                        keyindexdisklist.TryRemove(tablename, out oldindexarray);
                        keyindexdisklist.TryAdd(tablename, newdiskindexarray);
                        keyindexmemtemplist[tablename] = new SortArrayList <BigEntityTableIndexItem>();

                        int trycount = 0;
                        while (true)
                        {
                            try
                            {
                                File.Delete(indexfile);
                                ProcessTraceUtil.Trace("删除旧文件完成");
                                break;
                            }
                            catch (System.IO.IOException ex)
                            {
                                Thread.Sleep(1);
                                trycount++;
                                if (trycount > 1000)
                                {
                                    throw ex;
                                }
                            }
                        }

                        File.Move(newindexfile, indexfile);

                        ProcessTraceUtil.TraceMem("删除旧文件,重命名新文件完成", "m");

                        idxreader = null;
                    }
                    finally
                    {
                        tablelocker.ExitWriteLock();
                    }


                    string metafile = GetMetaFile(tablename);
                    mergeinfo.IndexMergePos = lasmargepos;
                    SerializerHelper.SerializerToXML(meta, metafile, true);

                    ProcessTraceUtil.Trace("更新元文件,更新索引完成");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("整理索引后面部分出错" + ex.ToString());

                    //LogManager.LogHelper.Instance.Error("整理索引后面部分出错", ex);
                }
                finally
                {
                    if (idxreader != null)
                    {
                        idxreader.Dispose();
                    }

                    if (newwriter != null && !newwriter.Isdispose)
                    {
                        newwriter.Dispose();
                    }

                    if (File.Exists(newindexfile))
                    {
                        File.Delete(newindexfile);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());

                //LogManager.LogHelper.Instance.Error("整理索引出错", ex);
            }
            finally
            {
                //GC.Collect();
                //ProcessTraceUtil.TraceMem("回收内存","m");
                mergeinfo.IsMergin = false;
                var info = ProcessTraceUtil.PrintTrace();
                Console.WriteLine(info);
                //LogManager.LogHelper.Instance.Debug("整理索引过程:" + info);
            }
        }
        private void LoadKey(string tablename, BigEntityTableMeta meta)
        {
            string indexfile      = GetKeyFile(tablename);
            var    indexmergeinfo = meta.IndexMergeInfos.Find(p => p.IndexName.Equals(meta.KeyName));

            if (indexmergeinfo == null)
            {
                indexmergeinfo           = new IndexMergeInfo();
                indexmergeinfo.IndexName = meta.KeyName;
                meta.IndexMergeInfos.Add(indexmergeinfo);
            }

            //计算加载因子
            indexmergeinfo.LoadFactor = (int)Math.Max(4, new FileInfo(indexfile).Length / MAX_KEYBUFFER);

            int i = 0;
            BigEntityTableIndexItem        lastreadindex = null;
            List <BigEntityTableIndexItem> list          = new List <BigEntityTableIndexItem>();
            long currentpos    = 0;
            long currrankindex = 0;

            byte[] buffer = new byte[1024 * 1024 * 10];
            using (ObjTextReader idx = ObjTextReader.CreateReader(indexfile))
            {
                Console.WriteLine("loadkey");
                foreach (var newindex in idx.ReadObjectsWating <BigEntityTableIndexItem>(1, p => currentpos = p, buffer))
                {
                    if (newindex.Del)
                    {
                        continue;
                    }
                    newindex.KeyOffset  = currentpos;
                    newindex.RangeIndex = currrankindex++;
                    newindex.SetIndex(meta.KeyIndexInfo);
                    if (newindex.KeyOffset >= indexmergeinfo.IndexMergePos)
                    {
                        //list.Add(newindex);
                        if (list.Count > 0)
                        {
                            if (list.Last().KeyOffset != lastreadindex.KeyOffset)
                            {
                                list.Add(lastreadindex);
                            }
                        }
                        break;
                    }

                    if (indexmergeinfo.LoadFactor == 1 || i % indexmergeinfo.LoadFactor == 0)
                    {
                        list.Add(newindex);
                    }
                    i++;
                    lastreadindex = newindex;
                }

                if (list.Count > 0 && list.Last().KeyOffset != lastreadindex.KeyOffset)
                {
                    list.Add(lastreadindex);
                }
            }
            indexmergeinfo.TotalCount = i;

            BigEntityTableIndexItem[] oldindexitems = null;
            keyindexdisklist.TryRemove(tablename, out oldindexitems);
            keyindexdisklist.TryAdd(tablename, list.ToArray());
            using (ObjTextReader idr = ObjTextReader.CreateReader(indexfile))
            {
                Console.WriteLine("loadkey2");

                if (indexmergeinfo.IndexMergePos > 0)
                {
                    idr.SetPostion(indexmergeinfo.IndexMergePos);
                }
                //Dictionary<string, BigEntityTableIndexItem> indexdic = new Dictionary<string, BigEntityTableIndexItem>();
                //keyindexlistdic[tablename];
                SortArrayList <BigEntityTableIndexItem> keymemlist = new SortArrayList <BigEntityTableIndexItem>();
                foreach (var newindex in idr.ReadObjectsWating <BigEntityTableIndexItem>(1, p => currentpos = p, buffer))
                {
                    newindex.KeyOffset = currentpos;
                    newindex.SetIndex(meta.KeyIndexInfo);
                    newindex.RangeIndex = -1;
                    if (!newindex.Del)
                    {
                        //indexdic.Add(newindex.Key, newindex);
                        keymemlist.Add(newindex);
                        i++;
                    }
                }

                var tablelocker = GetKeyLocker(tablename, string.Empty);
                tablelocker.EnterWriteLock();
                try
                {
                    foreach (var newindex in idr.ReadObjectsWating <BigEntityTableIndexItem>(1, p => currentpos = p, buffer))
                    {
                        newindex.KeyOffset = currentpos;
                        newindex.SetIndex(meta.KeyIndexInfo);
                        newindex.RangeIndex = -1;
                        if (!newindex.Del)
                        {
                            //indexdic.Add(newindex.Key, newindex);
                            keymemlist.Add(newindex);
                            i++;
                        }
                    }

                    if (idr.Length() - currentpos > 10240)
                    {
                        throw new Exception(tablename + "主键索引大量数据未读取");
                    }

                    //keyindexlistdic[tablename] = indexdic;
                    keyindexmemlist[tablename] = keymemlist;
                }
                finally
                {
                    tablelocker.ExitWriteLock();
                }
            }
        }
Ejemplo n.º 6
0
        public LocalFileQueue(string queuename, string queuefilepath, bool canwrite = true, bool canread = true)
        {
            if (string.IsNullOrWhiteSpace(queuename))
            {
                throw new ArgumentNullException("queuename");
            }
            QueueName = queuename;

            if (string.IsNullOrWhiteSpace(queuefilepath))
            {
                throw new ArgumentNullException("queuefilepath");
            }
            QueueFilePath = queuefilepath;

            if (!File.Exists(queuefilepath))
            {
                FileInfo file = new FileInfo(queuefilepath);
                if (!file.Directory.Exists)
                {
                    try
                    {
                        file.Directory.Create();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("创建文件夹失败:" + file.Directory.FullName, ex);
                    }
                }
            }

            if (canwrite)
            {
                //由于文件写是独占式的,当程序快速重启时,文件可能未及时释放
                int trytimes = 0;
                while (true)
                {
                    try
                    {
                        //_queueWriter = ObjTextWriter.CreateWriter(queuefilepath, ObjTextReaderWriterEncodeType.jsonbuf);
                        _queueWriter = ObjTextWriter.CreateWriter(queuefilepath, ObjTextReaderWriterEncodeType.entitybuf);
                        _queueWriter.Flush();
                        break;
                    }
                    catch (Exception ex)
                    {
                        trytimes++;
                        if (trytimes >= 3)
                        {
                            throw ex;
                        }
                        Thread.Sleep(1000 * trytimes);
                    }
                }
            }

            if (canread)
            {
                while (true)
                {
                    if (File.Exists(queuefilepath))
                    {
                        break;
                    }
                    Thread.Sleep(1000);
                }
                _queueReader = ObjTextReader.CreateReader(queuefilepath);

                FileInfo finfo = new FileInfo(queuefilepath);
                QueueCfgFile = finfo.Directory.FullName + "\\" + queuename + ".cfg";
                if (File.Exists(QueueCfgFile))
                {
                    _logger = LJC.FrameWork.Comm.SerializerHelper.DeSerializerFile <LocalFileQueueCfg>(QueueCfgFile, true);
                    if (_logger.LastPos > 0)
                    {
                        _queueReader.SetPostion(_logger.LastPos);
                    }
                }
                else
                {
                    _logger = new LocalFileQueueCfg();
                    _logger.LastChageTime = DateTime.Now;
                    _logger.QueueFile     = queuefilepath;
                    SaveConfig();
                }
            }

            _backtimer = new Timer(new TimerCallback(TimerAction), null, 0, 0);
        }