public override void WriteTo(IAreaWriter area) { int sz = Length; for (int i = 0; i < sz; ++i) { area.WriteByte(sparseByte); } }
public void CopyTo(IAreaWriter destination, int size) { const int BUFFER_SIZE = 2048; byte[] buf = new byte[BUFFER_SIZE]; int to_copy = System.Math.Min(size, BUFFER_SIZE); while (to_copy > 0) { Read(buf, 0, to_copy); destination.Write(buf, 0, to_copy); size -= to_copy; to_copy = System.Math.Min(size, BUFFER_SIZE); } }
private long WriteSingleVersionInfo(long versionId, NodeId rootNodeId, List <NodeId> deletedRefs) { int deletedRefCount = deletedRefs.Count; // Write the version info and the deleted refs to a new area, IAreaWriter writer = nodeStore.CreateArea(4 + 4 + 8 + 8 + 8 + 4 + (deletedRefCount * 16)); writer.WriteInt4(0x04EA23); writer.WriteInt4(1); writer.WriteInt8(versionId); writer.WriteInt8(rootNodeId.High); writer.WriteInt8(rootNodeId.Low); writer.WriteInt4(deletedRefCount); foreach (NodeId deletedNode in deletedRefs) { writer.WriteInt8(deletedNode.High); writer.WriteInt8(deletedNode.Low); } writer.Finish(); return(writer.Id); }
public override void WriteTo(IAreaWriter destArea) { area.Position = 12; area.CopyTo(destArea, Length); }
public bool Start() { lock (lockObject) { treeSystem = new StoreTreeSystem(store, branchNodeSize, leafNodeSize, heapNodeCacheSize, branchNodeCacheSize); treeSystem.Create(); treeSystem.CheckPoint(); // The actual database StoreTreeSystem treeStore; // Get the header area IArea headerArea = store.GetArea(-1); int magicValue = headerArea.ReadInt4(); // If header area magic value is zero, then we assume this is a brand // new database and initialize it with the configuration information // given. if (magicValue == 0) { // Create a tree store inside the file store, treeStore = new StoreTreeSystem(store, branchNodeSize, leafNodeSize, heapNodeCacheSize, branchNodeCacheSize); // Create the tree and returns a pointer to the tree, long treePointer = treeStore.Create(); // Create an area object with state information about the tree IAreaWriter awriter = store.CreateArea(128); awriter.WriteInt4(0x0101); // The version value awriter.WriteInt8(treePointer); awriter.WriteInt4(branchNodeSize); awriter.WriteInt4(leafNodeSize); awriter.Finish(); long dummy = awriter.Id; IMutableArea harea = store.GetMutableArea(-1); harea.WriteInt4(0x092BA001); // The magic value harea.WriteInt8(awriter.Id); harea.CheckOut(); } else if (magicValue == 0x092BA001) { long apointer = headerArea.ReadInt8(); // The area that contains configuration details, IArea initArea = store.GetArea(apointer); int version = initArea.ReadInt4(); if (version != 0x0101) { throw new IOException("Unknown version in tree initialization area"); } // Read the pointer to the tree store long treePointer = initArea.ReadInt8(); // Read the branch and leaf node sizes as set when the database was // created. int ibranchNodeSize = initArea.ReadInt4(); int ileafNodeSize = initArea.ReadInt4(); // Create the tree store treeStore = new StoreTreeSystem(store, ibranchNodeSize, ileafNodeSize, heapNodeCacheSize, branchNodeCacheSize); // Initialize the tree treeStore.Init(treePointer); } else { throw new IOException("Data is corrupt, invalid magic value in store"); } // Set the point of the tree store treeStore.CheckPoint(); // Set up final internal state and return true treeSystem = treeStore; databaseStarted = true; return(true); } }
public bool Start() { lock (lockObject) { // We can't start a database that is already started, if (databaseStarted || treeSystem != null) { return(false); } // Make a data.koi file with a single TreeSystem structure mapped into it const string fileExt = "cdb"; const string dbFileName = "data"; bufferManager = new LoggingBufferManager(path, path, false, maxPageCount, pageSize, fileExt, fileRolloverSize, logger, true); bufferManager.Start(); // The backing store fileStore = new JournalledFileStore(dbFileName, bufferManager, false); fileStore.Open(); // The actual database StoreTreeSystem treeStore; // Get the header area IArea headerArea = fileStore.GetArea(-1); int magicValue = headerArea.ReadInt4(); // If header area magic value is zero, then we assume this is a brand // new database and initialize it with the configuration information // given. if (magicValue == 0) { // Create a tree store inside the file store, treeStore = new StoreTreeSystem(fileStore, branchNodeSize, leafNodeSize, heapNodeCacheSize, branchNodeCacheSize); // Create the tree and returns a pointer to the tree, long treePointer = treeStore.Create(); // Create an area object with state information about the tree IAreaWriter awriter = fileStore.CreateArea(128); awriter.WriteInt4(0x0101); // The version value awriter.WriteInt8(treePointer); awriter.WriteInt4(branchNodeSize); awriter.WriteInt4(leafNodeSize); awriter.Finish(); long dummy = awriter.Id; IMutableArea harea = fileStore.GetMutableArea(-1); harea.WriteInt4(0x092BA001); // The magic value harea.WriteInt8(awriter.Id); harea.CheckOut(); } else if (magicValue == 0x092BA001) { long apointer = headerArea.ReadInt8(); // The area that contains configuration details, IArea initArea = fileStore.GetArea(apointer); int version = initArea.ReadInt4(); if (version != 0x0101) { throw new IOException("Unknown version in tree initialization area"); } // Read the pointer to the tree store long treePointer = initArea.ReadInt8(); // Read the branch and leaf node sizes as set when the database was // created. int ibranchNodeSize = initArea.ReadInt4(); int ileafNodeSize = initArea.ReadInt4(); // Create the tree store treeStore = new StoreTreeSystem(fileStore, ibranchNodeSize, ileafNodeSize, heapNodeCacheSize, branchNodeCacheSize); // Initialize the tree treeStore.Init(treePointer); } else { throw new IOException("Data is corrupt, invalid magic value in store"); } // Set the point of the tree store treeStore.CheckPoint(); // Set up final internal state and return true treeSystem = treeStore; databaseStarted = true; return(true); } }
public AreaOutputStream(IAreaWriter writer) { this.writer = writer; }
public override void WriteTo(IAreaWriter area) { area.Write(data, 0, Length); }
public override void WriteTo(IAreaWriter writer) { writer.Write(buffer, 6, Length); }
private void DisposeOldVersions() { List <object> disposeList = new List <object>(); lock (versions) { // size - 1 because we don't want to delete the very last version, int sz = versions.Count - 1; bool foundLockedEntry = false; for (int i = 0; i < sz && foundLockedEntry == false; ++i) { VersionInfo vinfo = versions[i]; // If this version isn't locked, if (vinfo.NotLocked) { // Add to the dispose list disposeList.Add(vinfo); // And delete from the versions list, versions.RemoveAt(i); --sz; --i; } else { // If it is locked, we exit the loop foundLockedEntry = true; } } } // If there are entries to dispose? if (disposeList.Count > 0) { // We synchronize here to ensure the versions list can't be modified by // a commit operation while we are disposing this. lock (this) { // Run within a write lock on the store try { nodeStore.LockForWrite(); // First we write out a modified version header minus the versions we // are to delete, // Get the current version list IMutableArea headerArea = nodeStore.GetMutableArea(headerId); headerArea.Position = 8; long versionListId = headerArea.ReadInt8(); // Read information from the old version info, IArea versionListArea = nodeStore.GetArea(versionListId); versionListArea.ReadInt4(); // The magic int versionCount = versionListArea.ReadInt4(); int newVersionCount = versionCount - disposeList.Count; // Create a new list, IAreaWriter newVersionList = nodeStore.CreateArea(8 + (8 * newVersionCount)); newVersionList.WriteInt4(0x01433); newVersionList.WriteInt4(newVersionCount); // Skip the versions we are deleting, for (int i = 0; i < disposeList.Count; ++i) { versionListArea.ReadInt8(); } // Now copy the list from the new point for (int i = 0; i < newVersionCount; ++i) { newVersionList.WriteInt8(versionListArea.ReadInt8()); } newVersionList.Finish(); // Write the new area to the header, headerArea.Position = 8; headerArea.WriteInt8(newVersionList.Id); // Delete the old version list Area, nodeStore.DeleteArea(versionListId); // Dispose the version info, int sz = disposeList.Count; for (int i = 0; i < sz; ++i) { VersionInfo vinfo = (VersionInfo)disposeList[i]; long vRef = vinfo.VersionInfoRef; IArea versionArea = nodeStore.GetArea(vRef); int magic = versionArea.ReadInt4(); int rev = versionArea.ReadInt4(); // Check the magic, if (magic != 0x04EA23) { throw new ApplicationException("Magic value for version area is incorrect."); } long verId = versionArea.ReadInt8(); long nrnHigh = versionArea.ReadInt8(); long nrnLow = versionArea.ReadInt8(); int nodeCount = versionArea.ReadInt4(); // For each node, for (int n = 0; n < nodeCount; ++n) { // Read the next area long drnHigh = versionArea.ReadInt8(); long drnLow = versionArea.ReadInt8(); NodeId delNodeId = new NodeId(drnHigh, drnLow); // Cleanly disposes the node DoDisposeNode(delNodeId); } // Delete the node header, nodeStore.DeleteArea(vRef); } } finally { nodeStore.UnlockForWrite(); } } } }
private long WriteVersionsList(long versionId, TreeSystemTransaction tran) { lock (this) { // Write the version info and the deleted refs to a new area, NodeId rootNodeId = tran.RootNodeId; if (rootNodeId.IsInMemory) { throw new ApplicationException("Assertion failed, root_node is on heap."); } // Get the list of all nodes deleted in the transaction List <NodeId> deletedRefs = tran.NodeDeletes; // Sort it deletedRefs.Sort(); // Check for any duplicate entries (we shouldn't double delete stuff). for (int i = 1; i < deletedRefs.Count; ++i) { if (deletedRefs[i - 1].Equals(deletedRefs[i])) { // Oops, duplicated delete throw new ApplicationException("PRAGMATIC_CHECK failed: duplicate records in delete list."); } } long theVersionId = WriteSingleVersionInfo(versionId, rootNodeId, deletedRefs); // Now update the version list by copying the list and adding the new ref // to the end. // Get the current version list IMutableArea headerArea = nodeStore.GetMutableArea(headerId); headerArea.Position = 8; long versionListId = headerArea.ReadInt8(); // Read information from the old version info, IArea versionListArea = nodeStore.GetArea(versionListId); versionListArea.ReadInt4(); // The magic int versionCount = versionListArea.ReadInt4(); // Create a new list, IAreaWriter newVersionList = nodeStore.CreateArea(8 + (8 * (versionCount + 1))); newVersionList.WriteInt4(0x01433); newVersionList.WriteInt4(versionCount + 1); for (int i = 0; i < versionCount; ++i) { newVersionList.WriteInt8(versionListArea.ReadInt8()); } newVersionList.WriteInt8(theVersionId); newVersionList.Finish(); // Write the new area to the header, headerArea.Position = 8; headerArea.WriteInt8(newVersionList.Id); // Delete the old version list Area, nodeStore.DeleteArea(versionListId); // Done, return(theVersionId); } }
public override void WriteTo(IAreaWriter dest) { area.Position = 12; area.CopyTo(dest, Length); }
public override void WriteTo(IAreaWriter area) { area.Write(data, 12, Length); }
public override void WriteTo(IAreaWriter writer) { writer.Write(data, 0, Length); }
public IList<long> Persist(TreeWrite write) { try { store.LockForWrite(); IList<ITreeNode> branches = write.BranchNodes; IList<ITreeNode> leafs = write.LeafNodes; List<ITreeNode> nodes = new List<ITreeNode>(branches.Count + leafs.Count); nodes.AddRange(branches); nodes.AddRange(leafs); // The list of nodes to be allocated, int sz = nodes.Count; // The list of allocated referenced for the nodes, long[] refs = new long[sz]; // The list of area writers, IAreaWriter[] areas = new IAreaWriter[sz]; // Allocate the space first, for (int i = 0; i < sz; ++i) { ITreeNode node = nodes[i]; if (node is TreeBranch) { TreeBranch branch = (TreeBranch)node; int ndsz = branch.DataSize; areas[i] = store.CreateArea(4 + 4 + (ndsz * 8)); } else { TreeLeaf leaf = (TreeLeaf)node; int lfsz = leaf.Length; areas[i] = store.CreateArea(12 + lfsz); } // Set the reference, refs[i] = areas[i].Id; } // Now write out the data, for (int i = 0; i < sz; ++i) { ITreeNode node = nodes[i]; // Is it a branch node? if (node is TreeBranch) { TreeBranch branch = (TreeBranch)node; // The number of children int chsz = branch.ChildCount; // For each child, if it's a heap node, look up the child id and // reference map in the sequence and set the reference accordingly, for (int o = 0; o < chsz; ++o) { long childId = branch.GetChild(o); if (childId < 0) { // The ref is currently on the heap, so adjust accordingly int refId = write.LookupRef(i, o); branch.SetChild(o, refs[refId]); } } // Write out the branch to the store long[] nodeData = branch.ChildPointers; int ndsz = branch.DataSize; IAreaWriter writer = areas[i]; writer.WriteInt2(BranchType); writer.WriteInt2(1); // version writer.WriteInt4(ndsz); for (int o = 0; o < ndsz; ++o) { writer.WriteInt8(nodeData[o]); } writer.Finish(); // Make this into a branch node and add to the cache, branch = new TreeBranch(refs[i], nodeData, ndsz); // Put this branch in the cache, lock (branchCache) { branchCache.Set(refs[i], branch); } } else { // Otherwise, it must be a leaf node, TreeLeaf leaf = (TreeLeaf)node; IAreaWriter area = areas[i]; area.WriteInt2(LeafType); area.WriteInt2(1); // version area.WriteInt4(1); // reference count area.WriteInt4(leaf.Length); leaf.WriteTo(area); area.Finish(); } } return refs; } finally { store.UnlockForWrite(); } }
public long Create() { if (initialized) { throw new InvalidOperationException("This tree store is already initialized."); } // Temporary node heap for creating a starting database TreeNodeHeap nodeHeap = new TreeNodeHeap(17, 4 * 1024 * 1024); // Write a root node to the store, // Create an empty head node TreeLeaf headLeaf = nodeHeap.CreateLeaf(null, Key.Head, 256); // Insert a tree identification pattern headLeaf.Write(0, new byte[] { 1, 1, 1, 1 }, 0, 4); // Create an empty tail node TreeLeaf tailLeaf = nodeHeap.CreateLeaf(null, Key.Tail, 256); // Insert a tree identification pattern tailLeaf.Write(0, new byte[] { 1, 1, 1, 1 }, 0, 4); // The write sequence, TreeWrite seq = new TreeWrite(); seq.NodeWrite(headLeaf); seq.NodeWrite(tailLeaf); IList <NodeId> refs = Persist(seq); // Create a branch, TreeBranch rootBranch = nodeHeap.CreateBranch(null, MaxBranchSize); rootBranch.Set(refs[0], 4, Key.Tail, refs[1], 4); seq = new TreeWrite(); seq.NodeWrite(rootBranch); refs = Persist(seq); // The written root node reference, NodeId rootId = refs[0]; // Delete the head and tail leaf, and the root branch nodeHeap.Delete(headLeaf.Id); nodeHeap.Delete(tailLeaf.Id); nodeHeap.Delete(rootBranch.Id); // Write this version info to the store, long versionId = WriteSingleVersionInfo(1, rootId, new List <NodeId>(0)); // Make a first version VersionInfo versionInfo = new VersionInfo(1, rootId, versionId); versions.Add(versionInfo); // Flush this to the version list IAreaWriter versionList = nodeStore.CreateArea(64); versionList.WriteInt4(0x01433); versionList.WriteInt4(1); versionList.WriteInt8(versionId); versionList.Finish(); // Get the versions id long versionListId = versionList.Id; // The final header IAreaWriter header = nodeStore.CreateArea(64); header.WriteInt4(0x09391); // The magic value, header.WriteInt4(1); // The version header.WriteInt8(versionListId); header.Finish(); // Set up the internal variables, headerId = header.Id; initialized = true; // And return the header reference return(headerId); }
public abstract void WriteTo(IAreaWriter area);
public IList <NodeId> Persist(TreeWrite write) { try { nodeStore.LockForWrite(); IList <ITreeNode> allBranches = write.BranchNodes; IList <ITreeNode> allLeafs = write.LeafNodes; List <ITreeNode> nodes = new List <ITreeNode>(allBranches.Count + allLeafs.Count); nodes.AddRange(allBranches); nodes.AddRange(allLeafs); // The list of nodes to be allocated, int sz = nodes.Count; // The list of allocated referenced for the nodes, NodeId[] refs = new NodeId[sz]; // The list of area writers, IAreaWriter[] writers = new IAreaWriter[sz]; // Allocate the space first, for (int i = 0; i < sz; ++i) { ITreeNode node = nodes[i]; // Is it a branch node? if (node is TreeBranch) { TreeBranch branch = (TreeBranch)node; int ndsz = branch.NodeDataSize; writers[i] = nodeStore.CreateArea(4 + 4 + (ndsz * 8)); } // Otherwise, it must be a leaf node, else { TreeLeaf leaf = (TreeLeaf)node; int lfsz = leaf.Length; writers[i] = nodeStore.CreateArea(12 + lfsz); } // Set the reference, refs[i] = FromInt64StoreAddress(writers[i].Id); } // Now write out the data, for (int i = 0; i < sz; ++i) { ITreeNode node = nodes[i]; // Is it a branch node? if (node is TreeBranch) { TreeBranch branch = (TreeBranch)node; // The number of children int chsz = branch.ChildCount; // For each child, if it's a heap node, look up the child id and // reference map in the sequence and set the reference accordingly, for (int o = 0; o < chsz; ++o) { NodeId childId = branch.GetChild(o); if (childId.IsInMemory) { // The ref is currently on the heap, so adjust accordingly int refId = write.LookupRef(i, o); branch.SetChild(refs[refId], o); } } // Write out the branch to the store long[] nodeData = branch.NodeData; int ndsz = branch.NodeDataSize; IAreaWriter writer = writers[i]; writer.WriteInt2(StoreBranchType); writer.WriteInt2(1); // version writer.WriteInt4(ndsz); for (int o = 0; o < ndsz; ++o) { writer.WriteInt8(nodeData[o]); } writer.Finish(); // Make this into a branch node and add to the cache, branch = new TreeBranch(refs[i], nodeData, ndsz); // Put this branch in the cache, lock (branchCache) { branchCache.Set(refs[i], branch); } } // Otherwise, it must be a leaf node, else { TreeLeaf leaf = (TreeLeaf)node; IAreaWriter writer = writers[i]; writer.WriteInt2(StoreLeafType); writer.WriteInt2(1); // version writer.WriteInt4(1); // reference count writer.WriteInt4(leaf.Length); leaf.WriteTo(writer); writer.Finish(); } } return(refs); } finally { nodeStore.UnlockForWrite(); } }
public override void WriteTo(IAreaWriter area) { ActualLeaf.WriteTo(area); }
public abstract void WriteTo(IAreaWriter area);
public override void WriteTo(IAreaWriter area) { int sz = Length; for (int i = 0; i < sz; ++i) { area.WriteByte(sparseByte); } }
public override void WriteTo(IAreaWriter area) { ActualLeaf.WriteTo(area); }
public void CopyTo(IAreaWriter dest, int size) { // NOTE: Assuming 'destination' is a StoreArea, the temporary buffer // could be optimized away to a direct System.arraycopy. However, this // function would need to be written as a lower level IO function. const int BUFFER_SIZE = 2048; byte[] buf = new byte[BUFFER_SIZE]; int to_copy = System.Math.Min(size, BUFFER_SIZE); while (to_copy > 0) { Read(buf, 0, to_copy); dest.Write(buf, 0, to_copy); size -= to_copy; to_copy = System.Math.Min(size, BUFFER_SIZE); } }
public void CopyTo(IAreaWriter destination, int size) { const int BUFFER_SIZE = 2048; byte[] buf = new byte[BUFFER_SIZE]; int to_copy = System.Math.Min(size, BUFFER_SIZE); while (to_copy > 0) { Read(buf, 0, to_copy); destination.Write(buf, 0, to_copy); size -= to_copy; to_copy = System.Math.Min(size, BUFFER_SIZE); } }