func (w *Writer) DeleteNode(x *skiplist.Node) (success bool) { defer func() { if success { w.count -= 1 } }() x.GClink = nil sn := w.getCurrSn() gotItem := (*Item)(x.Item()) if gotItem.bornSn == sn { success = w.store.DeleteNode(x, w.insCmp, w.buf, &w.slSts1) barrier := w.store.GetAccesBarrier() barrier.FlushSession(unsafe.Pointer(x)) return } success = atomic.CompareAndSwapUint32(&gotItem.deadSn, 0, sn) if success { if w.gctail == nil { w.gctail = x w.gchead = w.gctail } else { w.gctail.GClink = x w.gctail = x } } return }
func (m *MemDB) Close() { // Wait until all snapshot iterators have finished for s := m.snapshots.GetStats(); int(s.NodeCount) != 0; s = m.snapshots.GetStats() { time.Sleep(time.Millisecond) } m.hasShutdown = true // Acquire gc chan ownership // This will make sure that no other goroutine will write to gcchan for !atomic.CompareAndSwapInt32(&m.isGCRunning, 0, 1) { time.Sleep(time.Millisecond) } close(m.gcchan) buf := dbInstances.MakeBuf() defer dbInstances.FreeBuf(buf) dbInstances.Delete(unsafe.Pointer(m), CompareMemDB, buf, &dbInstances.Stats) if m.useMemoryMgmt { buf := m.snapshots.MakeBuf() defer m.snapshots.FreeBuf(buf) m.shutdownWg1.Wait() close(m.freechan) m.shutdownWg2.Wait() // Manually free up all nodes iter := m.store.NewIterator(m.iterCmp, buf) defer iter.Close() var lastNode *skiplist.Node iter.SeekFirst() if iter.Valid() { lastNode = iter.GetNode() iter.Next() } for lastNode != nil { m.freeItem((*Item)(lastNode.Item())) m.store.FreeNode(lastNode, &m.store.Stats) lastNode = nil if iter.Valid() { lastNode = iter.GetNode() iter.Next() } } } }