internal void Close(Table obj) { SyncOpen.WaitOne(); View vw = obj.Order; obj.LoTable = null; obj.Order = null; if (vw != null && vw.Close()) { SyncView.WaitOne(); ViewList.Remove(vw.getkey); SyncView.ReleaseMutex(); } if (OpenCount == 1) { string tmpfile = ""; if (MustPack) { Struct.LastUpdate = DateTime.Now; tmpfile = String.Format("{0}{1:yyyy}{1:MM}{1:dd}{1:HH}{1:mm}{1:ss}", Alias, Struct.LastUpdate); File.CopyTo(tmpfile, "BackupTable"); long r, w, x; w = 1; x = Struct.RowCount; for (r = 1; r <= x; r++) { Read(obj, r); if (!Deleted(obj)) { if (w != r) { obj.Buffer.Position = Data + (w - 1) * Struct.RowLength; File.Write(obj); } w++; } } Struct.LastUpdate = DateTime.Now; Struct.RowCount = w - 1; File.LoFile.SetLength(Data + Struct.RowLength * Struct.RowCount); } File.Write(Struct); File.Close(); if (MustPack) { DataFile.Delete(tmpfile, "BackupTable"); } OpenList.Remove(Alias); } else { OpenCount--; } SyncOpen.ReleaseMutex(); }
public void LinkParent(DataFile fle, ushort kl, int pgsz) { if (Parent == 0) { return; } IdxPage pa = new IdxPage(0, 0, 0, kl); long adr = this.Buffer.Position; string key = Table[Rows - 1].Key; fle.Read(pa, Parent, pgsz); for (ushort i = 0; i < pa.Rows; i++) { if (pa.Table[i].Address == adr) { pa.Table[i].Key = key; fle.Write(pa); if (i == pa.Rows - 1) { pa.LinkParent(fle, kl, pgsz); } return; } } throw new System.InvalidOperationException("MinBase: Index file " + fle.LoFile.Name + " corrupted: tying to find record by address"); }
public Index(string nm, ushort kl, DateTime udTime) { int sz = DataFile.GetSize(Root); if (DataFile.Exists(nm, "Index")) { File = DataFile.Open(nm, "Index", FileMode.Open); File.Read(Root, DataFile.coSignatureSz, sz); if (DateTime.Compare(Root.LastUpdate, udTime) >= 0 && Root.Closed) { Root.Closed = false; File.Lock(Root); File.Write(Root); return; } File.Close(); DataFile.Delete(nm, "Index"); } File = DataFile.Open(nm, "Index", FileMode.CreateNew); DataFile.Blank(Root, sz); Root.KeyLength = kl; Root.Closed = false; Root.PageSize = (ushort)DataFile.GetSize(new IdxPage(0, 0, 0, kl)); File.Append(Root, sz); File.Lock(Root); }
public void LinkChild(DataFile fle, long chadr, ushort kl, int pgsz) { IdxPage ch = new IdxPage(0, 0, 0, kl); fle.Read(ch, chadr, pgsz); ch.Parent = this.Buffer.Position; fle.Write(ch); }
public void Remove(DataFile fle, string key, long adr, bool branch, IdxRoot root, IdxPos pos) { ushort i; ushort row = pos.Row; int pgsz = root.PageSize; ushort kyln = root.KeyLength; if (Rows > coMin || Parent == 0) { if (Rows == 1) { root.Root = root.First = root.Last = 0; root.Levels = 0; fle.Write(root); return; } Rows--; if (row == Rows) { LinkParent(fle, kyln, pgsz); } else { for (i = row; i < Rows; i++) { Table[i].Key = Table[i + 1].Key; Table[i].Address = Table[i + 1].Address; } } fle.Write(this); fle.Write(root); return; } ushort pz, nz, f, t, dx; IdxPage pv, nx; if (Previous > 0) { pv = new IdxPage(0, 0, 0, kyln); fle.Read(pv, Previous, pgsz); pz = pv.Rows; } else { pv = null; pz = coOrder + coOrder; } if (Next > 0) { nx = new IdxPage(0, 0, 0, kyln); fle.Read(nx, Next, pgsz); nz = nx.Rows; } else { nx = null; nz = coOrder + coOrder; } Rows--; if (pz < nz) { if (pv.Rows == coMin) { t = coMin; f = 0; for (i = 0; i < Rows; i++) { if (i == row) { f++; } pv.Table[t].Key = Table[f].Key; pv.Table[t].Address = Table[f].Address; if (branch) { pv.LinkChild(fle, Table[f].Address, kyln, pgsz); } t++; f++; } pv.Rows += Rows; pv.Next = Next; if (Next == 0) { if (!branch) { root.Last = Previous; } if (pv.Previous == 0) { pv.Parent = 0; fle.Write(pv); root.Root = Previous; root.Levels--; fle.Write(root); return; } } else { nx.Previous = Previous; fle.Write(nx); } pv.LinkParent(fle, kyln, pgsz); fle.Write(pv); KeyOnParent(fle, kyln, pgsz, pos); pos.Page.Remove(fle, Table[Rows].Key, this.Buffer.Position, true, root, pos); return; } dx = (ushort)((pv.Rows - coMin) / 2); if (dx == 0) { dx = 1; } t = (ushort)(Rows + dx - 1); f = Rows; for (i = 0; i < Rows; i++) { if (f == row) { f--; } Table[t].Key = Table[f].Key; Table[t].Address = Table[f].Address; f--; t--; } f = (ushort)(pv.Rows - 1); for (i = 0; i < dx; i++) { Table[t].Key = pv.Table[f].Key; Table[t].Address = pv.Table[f].Address; if (branch) { LinkChild(fle, Table[t].Address, kyln, pgsz); } t--; f--; } pv.Rows -= dx; Rows += dx; if (row + dx == Rows) { LinkParent(fle, kyln, pgsz); } pv.LinkParent(fle, kyln, pgsz); fle.Write(pv); fle.Write(this); fle.Write(root); return; } if (nx.Rows == coMin) { f = (ushort)(nx.Rows - 1); t = (ushort)(f + Rows); for (i = 0; i < nx.Rows; i++) { nx.Table[t].Key = nx.Table[f].Key; nx.Table[t].Address = nx.Table[f].Address; t--; f--; } f = Rows; for (i = 0; i < Rows; i++) { if (f == row) { f--; } nx.Table[t].Key = Table[f].Key; nx.Table[t].Address = Table[f].Address; if (branch) { nx.LinkChild(fle, Table[f].Address, kyln, pgsz); } t--; f--; } nx.Rows += Rows; nx.Previous = Previous; if (Previous == 0) { if (!branch) { root.First = Next; } if (nx.Next == 0) { nx.Parent = 0; fle.Write(nx); root.Root = Next; root.Levels--; fle.Write(root); return; } } else { pv.Next = Next; fle.Write(pv); } fle.Write(nx); KeyOnParent(fle, kyln, pgsz, pos); pos.Page.Remove(fle, Table[Rows].Key, this.Buffer.Position, true, root, pos); return; } for (i = row; i < Rows; i++) { Table[i].Key = Table[i + 1].Key; Table[i].Address = Table[i + 1].Address; } dx = (ushort)((nx.Rows - coMin) / 2); if (dx == 0) { dx = 1; } t = Rows; f = 0; for (i = 0; i < dx; i++) { Table[t].Key = nx.Table[f].Key; Table[t].Address = nx.Table[f].Address; if (branch) { LinkChild(fle, Table[t].Address, kyln, pgsz); } f++; t++; } Rows += dx; nx.Rows -= dx; t = 0; for (i = 0; i < nx.Rows; i++) { nx.Table[t].Key = nx.Table[f].Key; nx.Table[t].Address = nx.Table[f].Address; t++; f++; } LinkParent(fle, kyln, pgsz); fle.Write(this); fle.Write(nx); fle.Write(root); }
public void Add(DataFile fle, string key, long adr, bool branch, IdxRoot root, IdxPos pos) { int i; ushort j, mx, p, q, m, dx; int pgsz = root.PageSize; ushort kyln = root.KeyLength; ushort row = pos.Row; if (pos.Result == IdxPos.coIxSmaller) { row++; } if (Rows < coOrder) { for (i = Rows; i > row; i--) { Table[i].Key = Table[i - 1].Key; Table[i].Address = Table[i - 1].Address; } Table[row].Key = key; Table[row].Address = adr; Rows++; if (row == Rows - 1) { LinkParent(fle, kyln, pgsz); } if (root.Root == 0) { fle.Append(this, pgsz); root.Levels = 1; root.Root = root.First = root.Last = this.Buffer.Position; } else { fle.Write(this); if (branch) { LinkChild(fle, adr, kyln, pgsz); } } fle.Write(root); return; } IdxPage si = new IdxPage(0, 0, 0, kyln); if (Previous > 0) { fle.Read(si, Previous, root.PageSize); if (si.Rows < coOrder) { dx = (ushort)((coOrder - si.Rows) / 2); if (dx == 0) { dx = 1; } if (row < dx) { p = (ushort)(si.Rows + row); q = coOrder + 1; if (dx == 1) { si.Table[si.Rows].Key = key; si.Table[si.Rows].Address = adr; si.Rows++; fle.Write(si); si.LinkParent(fle, kyln, pgsz); if (branch) { si.LinkChild(fle, adr, kyln, pgsz); } return; } } else { p = coOrder + 1; q = (ushort)(row - dx); } for (i = 0; i < dx; i++) { if (si.Rows == p) { si.Table[si.Rows].Key = key; si.Table[si.Rows].Address = adr; si.Rows++; if (branch) { si.LinkChild(fle, adr, kyln, pgsz); } dx--; if (dx == i) { break; } } si.Table[si.Rows].Key = Table[i].Key; si.Table[si.Rows].Address = Table[i].Address; si.Rows++; if (branch) { si.LinkChild(fle, Table[i].Address, kyln, pgsz); } } si.LinkParent(fle, kyln, pgsz); fle.Write(si); mx = (ushort)(coOrder - dx); j = dx; m = 0; for (i = 0; i < mx; i++) { if (m == q) { Table[m].Key = key; Table[m].Address = adr; if (branch) { LinkChild(fle, adr, kyln, pgsz); } m++; dx--; if (m == j) { break; } } Table[m].Key = Table[j].Key; Table[m].Address = Table[j].Address; m++; j++; } Rows -= dx; if (q == Rows) { Table[q].Key = key; Table[q].Address = adr; Rows++; if (branch) { LinkChild(fle, adr, kyln, pgsz); } } if (q == Rows - 1) { LinkParent(fle, kyln, pgsz); } fle.Write(this); fle.Write(root); return; } } if (Next > 0) { fle.Read(si, Next, pgsz); if (si.Rows < coOrder) { dx = (ushort)((coOrder - si.Rows) / 2); if (dx == 0) { dx = 1; } mx = (ushort)(Rows - dx); if (row > mx) { p = (ushort)(row - mx - 1); } else { p = coOrder + 1; } m = (ushort)(si.Rows + dx - 1); j = (ushort)(m - dx); for (i = 0; i < si.Rows; i++) { si.Table[m].Key = si.Table[j].Key; si.Table[m].Address = si.Table[j].Address; m--; j--; } si.Rows += dx; m = (ushort)(dx - 1); j = coOrder - 1; for (i = 0; i < dx; i++) { if (m == p) { si.Table[m].Key = key; si.Table[m].Address = adr; if (branch) { si.LinkChild(fle, adr, kyln, pgsz); } dx--; if (m == 0) { break; } m--; } si.Table[m].Key = Table[j].Key; si.Table[m].Address = Table[j].Address; if (branch) { si.LinkChild(fle, Table[j].Address, kyln, pgsz); } m--; j--; } Rows -= dx; if (p == coOrder + 1) { for (i = Rows; i > row; i--) { Table[i].Key = Table[i - 1].Key; Table[i].Address = Table[i - 1].Address; } Table[row].Key = key; Table[row].Address = adr; if (branch) { LinkChild(fle, adr, kyln, pgsz); } Rows++; } LinkParent(fle, kyln, pgsz); fle.Write(this); fle.Write(si); fle.Write(root); return; } } si = new IdxPage(Parent, this.Buffer.Position, Next, kyln); IdxPage pa; ushort mv = si.Rows = Rows = coMin; ushort hp, wr; long thad; string skey; if (row >= coMin) { hp = (ushort)(row - coMin); } else { hp = coOrder; } wr = 0; for (i = 0; i < coMin; i++) { if (i == hp) { si.Table[wr].Key = key; si.Table[wr].Address = adr; wr++; si.Rows++; } si.Table[wr].Key = Table[mv].Key; si.Table[wr].Address = Table[mv].Address; wr++; mv++; } if (hp == coMin) { si.Table[coMin].Key = key; si.Table[coMin].Address = adr; si.Rows++; } fle.Append(si, pgsz); Next = si.Buffer.Position; if (branch) { for (i = 0; i < si.Rows; i++) { si.LinkChild(fle, si.Table[i].Address, kyln, pgsz); } } if (si.Rows == Rows) { for (i = Rows; i > row; i--) { Table[i].Key = Table[i - 1].Key; Table[i].Address = Table[i - 1].Address; } Table[row].Key = key; Table[row].Address = adr; if (branch) { LinkChild(fle, adr, kyln, pgsz); } Rows++; } if (si.Next == 0) { if (!branch) { root.Last = Next; } if (Parent == 0) { pa = new IdxPage(0, 0, 0, kyln); pa.Rows = 2; pa.Table[0].Key = Table[Rows - 1].Key; pa.Table[0].Address = si.Previous; pa.Table[1].Key = si.Table[si.Rows - 1].Key; pa.Table[1].Address = Next; fle.Append(pa, pgsz); Parent = si.Parent = pa.Buffer.Position; fle.Write(this); fle.Write(si); root.Root = Parent; root.Levels++; fle.Write(root); return; } } else { IdxPage ss = new IdxPage(0, 0, 0, kyln); fle.Read(ss, si.Next, pgsz); ss.Previous = Next; fle.Write(ss); } LinkParent(fle, kyln, pgsz); fle.Write(this); skey = si.Table[si.Rows - 1].Key; thad = this.Buffer.Position; pa = new IdxPage(0, 0, 0, kyln); fle.Read(pa, Parent, pgsz); for (j = 0; j < pa.Rows; j++) { if (pa.Table[j].Address == thad) { pos.Row = j; pos.Result = IdxPos.coIxSmaller; pa.Add(fle, skey, Next, true, root, pos); return; } } throw new System.InvalidOperationException("MinBase: Index file " + fle.LoFile.Name + " corrupted, trying to add key."); }
public void Close() { Root.Closed = true; File.Write(Root); File.Close(); }