public HeapTreeLeaf(TreeSystemTransaction transaction, NodeId nodeId, int maxCapacity) { this.nodeId = nodeId; size = 0; this.transaction = transaction; data = new byte[maxCapacity]; }
public TreeBranch CreateBranch(TreeSystemTransaction tran, int maxBranchChildren) { NodeId p = NextNodePointer(); HeapTreeBranch node = new HeapTreeBranch(tran, p, maxBranchChildren); PutInHash(node); return(node); }
public TreeLeaf CreateLeaf(TreeSystemTransaction tran, Key key, int maxLeafSize) { NodeId p = NextNodePointer(); HeapTreeLeaf node = new HeapTreeLeaf(tran, p, maxLeafSize); PutInHash(node); return(node); }
public HeapTreeLeaf(TreeSystemTransaction transaction, NodeId nodeId, TreeLeaf toCopy, int capacity) { this.nodeId = nodeId; size = toCopy.Length; this.transaction = transaction; // Copy the data into an array in this leaf. data = new byte[capacity]; toCopy.Read(0, data, 0, size); }
public TreeSystemStack(TreeSystemTransaction ts) { this.ts = ts; stackSize = 0; stack = new long[StackFrameSize * 13]; currentLeaf = null; currentLeafKey = null; leafOffset = 0; }
public void Commit(ITransaction tran) { CheckErrorState(); try { TreeSystemTransaction transaction = (TreeSystemTransaction)tran; VersionInfo topVersion; lock (versions) { topVersion = versions[versions.Count - 1]; } // Check the version is based on the must current transaction, if (transaction.VersionId != topVersion.VersionId) { // ID not the same as the top version, so throw the exception throw new ApplicationException("Can't commit non-sequential version."); } // Make sure the transaction is written to the store, // NOTE: This MUST happen outside a node store lock otherwise checking // out on the cache manage function could lock up the thread transaction.Checkout(); try { nodeStore.LockForWrite(); // The new version number, long newVersionNum = topVersion.VersionId + 1; // Write out the versions list to the store, long versionRecordId = WriteVersionsList(newVersionNum, transaction); // Create a new VersionInfo object with a new id, VersionInfo newVinfo = new VersionInfo(newVersionNum, transaction.RootNodeId, versionRecordId); lock (versions) { // Add this version to the end of the versions list, versions.Add(newVinfo); } } finally { nodeStore.UnlockForWrite(); } // Notify the transaction is committed, // This will stop the transaction from cleaning up newly added nodes. transaction.OnCommitted(); } catch (IOException e) { // An IOException during this block represents a critical stopping // condition. throw SetErrorState(e); } catch (OutOfMemoryException e) { // An out-of-memory error represents a critical state that causes // immediate cleanup. throw SetErrorState(e); } }
internal DataRange(TreeSystemTransaction transaction, Key lowerKey, Key upperKey) { stack = new TreeSystemStack(transaction); this.lowerKey = transaction.PreviousKeyOrder(lowerKey); this.transaction = transaction; this.upperKey = upperKey; p = 0; version = -1; start = -1; end = -1; }
internal DataFile(TreeSystemTransaction transaction, Key key, bool fileReadOnly) { stack = new TreeSystemStack(transaction); this.transaction = transaction; this.key = key; p = 0; version = -1; this.fileReadOnly = fileReadOnly; start = -1; end = -1; }
public void Dispose(ITransaction tran) { CheckErrorState(); try { TreeSystemTransaction transaction = (TreeSystemTransaction)tran; // Get the version id of the transaction, long versionId = transaction.VersionId; // Call the dispose method, transaction.Dispose(); // Reduce the lock count for this version id, UnlockTransaction(versionId); // Check if we can clear up old versions, DisposeOldVersions(); } catch (IOException e) { // An IOException during this block represents a critical stopping // condition. throw SetErrorState(e); } catch (OutOfMemoryException e) { // An out-of-memory error represents a critical state that causes // immediate cleanup. throw SetErrorState(e); } }
public HeapTreeBranch(TreeSystemTransaction transaction, NodeId nodeId, TreeBranch branch, int maxChildrenCount) : base(nodeId, branch, maxChildrenCount) { this.transaction = transaction; }
internal void FlushCache() { IList <IHashNode> toFlush = null; // If the memory use is above some limit then we need to flush out some // of the nodes, if (memoryUsed > maxMemoryLimit) { int allNodeCount = totalBranchNodeCount + totalLeafNodeCount; // The number to clean, int toClean = (int)(allNodeCount * 0.30); // Make an array of all nodes to flush, toFlush = new List <IHashNode>(toClean); // Pull them from the back of the list, IHashNode node = hashEnd; while (toClean > 0 && node != null) { toFlush.Add(node); node = node.Previous; --toClean; } } // If there are nodes to flush, if (toFlush != null) { // Read each group and call the node flush routine, // The mapping of transaction to node list Dictionary <TreeSystemTransaction, List <NodeId> > tranMap = new Dictionary <TreeSystemTransaction, List <NodeId> >(); // Read the list backwards, for (int i = toFlush.Count - 1; i >= 0; --i) { IHashNode node = toFlush[i]; // Get the transaction of this node, TreeSystemTransaction tran = node.Transaction; // Find the list of this transaction, List <NodeId> nodeList = tranMap[tran]; if (nodeList == null) { nodeList = new List <NodeId>(toFlush.Count); tranMap.Add(tran, nodeList); } // Add to the list nodeList.Add(node.Id); } // Now read the key and dispatch the clean up to the transaction objects, foreach (KeyValuePair <TreeSystemTransaction, List <NodeId> > pair in tranMap) { TreeSystemTransaction tran = pair.Key; List <NodeId> nodeList = pair.Value; // Convert to a 'NodeId[]' array, NodeId[] refs = nodeList.ToArray(); // Sort the references, Array.Sort(refs); // Tell the transaction to clean up these nodes, tran.FlushNodesToStore(refs); } } }
public ITreeNode Copy(ITreeNode nodeToCopy, int maxBranchSize, int maxLeafSize, TreeSystemTransaction tran) { // Create a new pointer for the copy NodeId p = NextNodePointer(); IHashNode node; if (nodeToCopy is TreeLeaf) { node = new HeapTreeLeaf(tran, p, (TreeLeaf)nodeToCopy, maxLeafSize); } else { node = new HeapTreeBranch(tran, p, (TreeBranch)nodeToCopy, maxBranchSize); } PutInHash(node); // Return pointer to node return(node); }
public PlaceholderLeaf(TreeSystemTransaction ts, NodeId nodeId, int size) { this.ts = ts; this.nodeId = nodeId; this.size = size; }
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); } }