code: func gcasComplete(i *iNode, m *mainNode, ctrie *Ctrie) *mainNode {
  	for {
  		if m == nil {
  			return nil
  		}
  		prev := (*mainNode)(atomic.LoadPointer(
  			(*unsafe.Pointer)(unsafe.Pointer(&m.prev))))
  		root := ctrie.rdcssReadRoot(true)
  		if prev == nil {
  			return m
  		}
  
  		if prev.failed != nil {
  			// Signals GCAS failure. Swap old value back into I-node.
  			fn := prev.failed
  			if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&i.main)),
  				unsafe.Pointer(m), unsafe.Pointer(fn)) {
  				return fn
  			}
  			m = (*mainNode)(atomic.LoadPointer(
  				(*unsafe.Pointer)(unsafe.Pointer(&i.main))))
  			continue
  		}
  
  		if root.gen == i.gen && !ctrie.readOnly {
  			// Commit GCAS.
  			if atomic.CompareAndSwapPointer(
  				(*unsafe.Pointer)(unsafe.Pointer(&m.prev)), unsafe.Pointer(prev), nil) {
  				return m
  			}
  			continue
  		}
  
  		// Generations did not match. Store failed node on prev to signal
  		// I-node's main node must be set back to the previous value.
  		atomic.CompareAndSwapPointer(
  			(*unsafe.Pointer)(unsafe.Pointer(&m.prev)),
  			unsafe.Pointer(prev),
  			unsafe.Pointer(&mainNode{failed: prev}))
  		m = (*mainNode)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&i.main))))
  		return gcasComplete(i, m, ctrie)
  	}
  }
docs: // gcasComplete commits the GCAS operation.