C#实现的内存分页机制的一个实例
C#实现的内存分页机制的一个实例
//多页索引表管理类(全局主索引表管理类) public class MuliPageIndexFeatureClass : IDisposable { protected List<IndexPageClass> MuliPageIndexTable = new List<IndexPageClass>(); //多页索引表对象 // protected int CurrentMemoryPageIndex = -1; //当前内存索引页(已载入内存的索引页的对象) public int PerPageDwCount = 30000; //每页地物个数 default=3,0000 /// <summary> /// = Application.StartupPath + "\\tempfiles\\tmp_vct"; /// </summary> protected string tmpDir = Application.StartupPath + "\\tempfiles\\tmp_vct"; public MuliPageIndexFeatureClass() { this.MemoryPageList.Clear(); //txt存放目录 string dir = this.tmpDir; if (System.IO.Directory.Exists(dir) == true) { try { System.IO.Directory.Delete(dir, true); } catch { } } if(System.IO.Directory.Exists(dir) == false) { System.IO.Directory.CreateDirectory(dir); } } //创建多页索引表(建立多页索引表) 派生类需重写 private IndexPageClass tmpIP = null; public virtual bool CreateMuliPageIndexTable(FeatureOIDMap pfeat) { //txt存放目录 string dir = this.tmpDir; if (System.IO.Directory.Exists(dir) == false) { System.IO.Directory.CreateDirectory(dir); } //创建多页索引表.... if (this.tmpIP == null) { //产生一个新的索引页面 this.tmpIP = new IndexPageClass(); tmpIP.RelationFileName = "vctline" + this.MuliPageIndexTable.Count.ToString() + ".txt"; tmpIP.CreatedIndex = false; tmpIP.OpenTxt(); this.MuliPageIndexTable.Add(tmpIP); } else { if (tmpIP.dt.Count >=this.PerPageDwCount) { //保存原有的索引页面 tmpIP.SaveToTxt(); tmpIP.CloseTxt(); tmpIP.CreatedIndex = true; tmpIP.dt.Clear(); //产生一个新的索引页面 tmpIP = new IndexPageClass(); tmpIP.RelationFileName = "vctline" + this.MuliPageIndexTable.Count.ToString() + ".txt"; tmpIP.CreatedIndex = false; tmpIP.OpenTxt(); this.MuliPageIndexTable.Add(tmpIP); } } if(tmpIP!=null) { tmpIP.dt.Add(pfeat.ObjectID,pfeat); if (tmpIP.dt.Count % 100==0) { Application.DoEvents(); } } return true; } public virtual bool SaveEndPageIndexTable() { bool rbc = false; if (tmpIP != null) { tmpIP.SaveToTxt(); tmpIP.CloseTxt(); tmpIP.CreatedIndex = true; tmpIP.dt.Clear(); tmpIP.Dispose(); tmpIP = null; rbc = true; } return rbc; } //选择记录集 OK private List<int> MemoryPageList = new List<int>(); private int MemoryPagesOnLine = 7; //在线的内存索引文件数 public FeatureOIDMap GetLine(int bsm) { FeatureOIDMap feat = null; bool IsSearch = true; //是否要进行分页搜索操作标志 默认为是 if (this.CurrentMemoryPageIndex != -1) { //当前内存分页中是否有dwID地物唯一编号 if (this.MuliPageIndexTable[this.CurrentMemoryPageIndex].DwidList.Contains(bsm) == true) { IsSearch = false; } } if (IsSearch == true) { //进行分页搜索操作 并置为当前内存分页 for (int i = 0; i < this.MuliPageIndexTable.Count; i++) { if (this.MuliPageIndexTable[i].DwidList.Contains(bsm) == true) { if (this.CurrentMemoryPageIndex != i) { //需搜索页面不在当前内存页面中 (需置换页面) if (this.CurrentMemoryPageIndex != -1) { //修正在线内存索引文件个数 if (this.MemoryPageList.Contains(i) == false) { this.MemoryPageList.Add(i); } if (this.MemoryPageList.Contains(this.CurrentMemoryPageIndex) == false) { this.MemoryPageList.Add(this.CurrentMemoryPageIndex); } if (this.MemoryPageList.Count > this.MemoryPagesOnLine) { this.MemoryPageList.RemoveAt(0); } //清除离线内存索引文件中坐标大数据 for (int k = 0; k < this.MuliPageIndexTable.Count; k++) { if (this.MemoryPageList.Contains(k) == false) { this.MuliPageIndexTable[k].Dispose(); } } } if (this.MuliPageIndexTable[i].dt.Count <= 0) { this.MuliPageIndexTable[i].ReadFromTxt(); //从txt文件中读取记录 } this.CurrentMemoryPageIndex = i; break; } } //end if } //end for } //当前分面页页进行搜索... if (this.CurrentMemoryPageIndex != -1) { feat = this.MuliPageIndexTable[this.CurrentMemoryPageIndex].GetLine(bsm); } return feat; } //获取一页索引表 public IndexPageClass GetIndexPageClass(int index) { if (MuliPageIndexTable != null && this.MuliPageIndexTable.Count > index) { return this.MuliPageIndexTable[index]; } return null; } public void Clear() { this.Dispose(); } #region IDisposable 成员 public void Dispose() { if (this.MuliPageIndexTable.Count > 0) { for (int i = 0; i < this.MuliPageIndexTable.Count; i++) { this.MuliPageIndexTable[i].Dispose(); } } this.MuliPageIndexTable.Clear(); this.CurrentMemoryPageIndex = -1; } public void DeleteTempFile() { //分页对应的txt文件... string dir = this.tmpDir; if (System.IO.Directory.Exists(dir) == true) { try { System.IO.Directory.Delete(dir, true); } catch { } } } #endregion }
//一页内索引表管理类 public class IndexPageClass : IDisposable { public bool CreatedIndex = false; public List<int> DwidList = new List<int>(); //地物唯一编号的集合 public string RelationFileDir = Application.StartupPath + "\\tempfiles\\tmp_vct"; //相关的txt文件 dltb_xzdw_Relation_1.txt public string RelationFileName = ""; //排序后的记录关系记录DataRow集合 //从_1.txt从读取内容 protected FeatureOIDMapCollection m_dt = new FeatureOIDMapCollection(); protected System.IO.StreamWriter sw = null; private int m_index = 0; //get dt public FeatureOIDMapCollection dt { get { return m_dt; } } /// <summary> /// //打开文本分页文件写入流 /// </summary> public bool OpenTxt() { string relfilename = this.RelationFileDir + "\\" + this.RelationFileName; if (System.IO.File.Exists(relfilename) == true) { System.IO.File.Delete(relfilename); } this.sw = new StreamWriter(relfilename, true, Encoding.Default); return true; } /// <summary> /// 向写入流写入一行记录 /// </summary> private bool AppentLine(string pLine) { if (this.sw != null) { this.sw.WriteLine(pLine); this.m_index += 1; if (this.m_index % 10000 == 0) { this.sw.Flush(); Application.DoEvents(); } } return true; } /// <summary> /// 向写入流写入一行记录 /// </summary> private bool AppentLine(FeatureOIDMap pFeatureOIDMap) { StringBuilder pline = new StringBuilder(); CoPointClass cpoint = null; //常住内存索引 this.DwidList.Add(pFeatureOIDMap.ObjectID); // pline.Append(pFeatureOIDMap.ObjectID.ToString()); for (int i = 0; i < pFeatureOIDMap.PointArray.Count; i++) { cpoint=pFeatureOIDMap.PointArray[i] as CoPointClass; pline.Append("," + cpoint.X.ToString() + "," + cpoint.Y.ToString()); } return AppentLine(pline.ToString()); } //保存到txt文件中 public bool SaveToTxt() { bool rbc = false; if (this.dt != null) { foreach(FeatureOIDMap featmap in this.dt.Values) { this.AppentLine(featmap); } rbc = true; } return rbc; } /// <summary> /// 关闭写入流 /// </summary> public bool CloseTxt() { if (sw != null) { sw.Flush(); sw.Close(); sw.Dispose(); sw = null; } return true; } //从txt中读取记录到m_dt表中 OK public virtual bool ReadFromTxt() { this.Dispose(); int t_index = 0; int bsm=0; double x = 0; double y = 0; System.IO.StreamReader sr = new System.IO.StreamReader(this.RelationFileDir + "\\" + this.RelationFileName, Encoding.Default); string line = sr.ReadLine(); while (line != null && line != "") { t_index += 1; if (t_index % 100 == 0) { Application.DoEvents(); } //向m_dt中加入一行记录 string[] lineArray = line.Split(new char[] { ',' }); bsm=int.Parse(lineArray[0]); FeatureOIDMap feat_new = new FeatureOIDMap(bsm); for (int i = 1; i < lineArray.Length; i+=2) { CoPointClass xpPoint = new CoPointClass(); x = 0; y = 0; double.TryParse(lineArray[i], out x); double.TryParse(lineArray[i+1], out y); xpPoint.X = x; xpPoint.Y = y; // feat_new.PointArray.Add(xpPoint); } this.m_dt.Add(feat_new.ObjectID,feat_new); // line = sr.ReadLine(); } sr.Close(); sr.Dispose(); sr = null; return true; } //从内存页面中选择记录集 OK public FeatureOIDMap GetLine(int bsm) { FeatureOIDMap feat = null; if (m_dt != null && m_dt.Count <= 0) { this.ReadFromTxt(); } if (m_dt != null && m_dt.Count > 0) { feat = this.m_dt.GetIndexByOID(bsm); } return feat; } #region IDisposable 成员 public void Dispose() { if (m_dt != null) { m_dt.Clear(); } } #endregion }