public override void Debug_Dump(bool detailed) { Contract.Requires(m_start != null && m_current != null); Value *current = (Value *)m_start; Value *end = (Value *)m_current; Trace.WriteLine(" # ValuePage: count=" + m_count.ToString("N0") + ", used=" + this.MemoryUsage.ToString("N0") + ", capacity=" + m_capacity.ToString("N0") + ", start=0x" + new IntPtr(m_start).ToString("X8") + ", end=0x" + new IntPtr(m_current).ToString("X8")); if (detailed) { while (current < end) { Trace.WriteLine(" - [" + Entry.GetObjectType(current).ToString() + "] 0x" + new IntPtr(current).ToString("X8") + " : " + current->Header.ToString("X8") + ", seq=" + current->Sequence + ", size=" + current->Size + " : " + Value.GetData(current).ToSlice().ToAsciiOrHexaString()); if (current->Previous != null) { Trace.WriteLine(" -> Previous: [" + Entry.GetObjectType(current->Previous) + "] 0x" + new IntPtr(current->Previous).ToString("X8")); } if (current->Parent != null) { Trace.WriteLine(" <- Parent: [" + Entry.GetObjectType(current->Parent) + "] 0x" + new IntPtr(current->Parent).ToString("X8")); } current = Value.WalkNext(current); } } }
public void Collect(Page target, ulong sequence) { var current = (Value *)m_start; var end = (Value *)m_current; while (current < end) { bool keep = Value.StillAlive(current, sequence); void *parent = current->Parent; if (keep) { // copy to the target page var moved = target.TryAppend(current); if (moved == null) { throw new InvalidOperationException(); // ?? } // update the parent switch (Entry.GetObjectType(parent)) { case EntryType.Key: { ((Key *)parent)->Values = moved; break; } case EntryType.Value: { ((Value *)parent)->Previous = moved; break; } case EntryType.Free: { //NO-OP break; } default: { throw new InvalidOperationException("Unexpected parent while moving value"); } } current->Header |= Entry.FLAGS_MOVED | Entry.FLAGS_DISPOSED; } else { // we need to kill the link from the parent switch (Entry.GetObjectType(parent)) { case EntryType.Key: { ((Key *)parent)->Values = null; break; } case EntryType.Value: { ((Value *)parent)->Previous = null; break; } case EntryType.Free: { //NO-OP break; } default: { throw new InvalidOperationException("Unexpected parent while destroying value"); } } current->Header |= Entry.FLAGS_DISPOSED; } current = Value.WalkNext(current); } }