func (r *Root) GarbageCollect(ticket *time.Ticket) int {
	count := 0
	for _, pair := range r.removedElementPairMapByCreatedAt {
		if pair.elem.RemovedAt() != nil && ticket.Compare(pair.elem.RemovedAt()) >= 0 {
			pair.parent.Purge(pair.elem)
			count += r.garbageCollect(pair.elem)
		}
	}
	for _, text := range r.removedNodeTextElementMapByCreatedAt {
		removedNodeCnt := text.cleanupRemovedNodes(ticket)
		if removedNodeCnt > 0 {
			delete(r.removedNodeTextElementMapByCreatedAt, text.CreatedAt().Key())
		}
		count += removedNodeCnt
	}
	return count
}
GarbageCollect purge elements that were removed before the given time.
package json
import (
	"github.com/yorkie-team/yorkie/pkg/document/time"
)
type ElementPair struct {
	parent Container
	elem   Element
}
type Root struct {
	object                               *Object
	elementMapByCreatedAt                map[string]Element
	removedElementPairMapByCreatedAt     map[string]ElementPair
	removedNodeTextElementMapByCreatedAt map[string]TextElement
}
func NewRoot(root *Object) *Root {
	r := &Root{
		elementMapByCreatedAt:                make(map[string]Element),
		removedElementPairMapByCreatedAt:     make(map[string]ElementPair),
		removedNodeTextElementMapByCreatedAt: make(map[string]TextElement),
	}
	r.object = root
	r.RegisterElement(root)
	root.Descendants(func(elem Element, parent Container) bool {
		r.RegisterElement(elem)
		return false
	})
	return r
}
func (r *Root) Object() *Object {
	return r.object
}
func (r *Root) FindByCreatedAt(createdAt *time.Ticket) Element {
	return r.elementMapByCreatedAt[createdAt.Key()]
}
func (r *Root) RegisterElement(elem Element) {
	r.elementMapByCreatedAt[elem.CreatedAt().Key()] = elem
}
func (r *Root) DeregisterElement(elem Element) {
	createdAt := elem.CreatedAt().Key()
	delete(r.elementMapByCreatedAt, createdAt)
	delete(r.removedElementPairMapByCreatedAt, createdAt)
}
func (r *Root) RegisterRemovedElementPair(parent Container, elem Element) {
	r.removedElementPairMapByCreatedAt[elem.CreatedAt().Key()] = ElementPair{
		parent,
		elem,
	}
}
func (r *Root) RegisterRemovedNodeTextElement(textType TextElement) {
	r.removedNodeTextElementMapByCreatedAt[textType.CreatedAt().Key()] = textType
}
func (r *Root) DeepCopy() *Root {
	return NewRoot(r.object.DeepCopy().(*Object))
}