github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/callgraph/vta/internal/trie/builder.go (about)

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package trie
     6  
     7  // Collision functions combine a left and right hand side (lhs and rhs) values
     8  // the two values are associated with the same key and produces the value that
     9  // will be stored for the key.
    10  //
    11  // Collision functions must be idempotent:
    12  //   collision(x, x) == x for all x.
    13  // Collisions functions may be applied whenever a value is inserted
    14  // or two maps are merged, or intersected.
    15  type Collision func(lhs interface{}, rhs interface{}) interface{}
    16  
    17  // TakeLhs always returns the left value in a collision.
    18  func TakeLhs(lhs, rhs interface{}) interface{} { return lhs }
    19  
    20  // TakeRhs always returns the right hand side in a collision.
    21  func TakeRhs(lhs, rhs interface{}) interface{} { return rhs }
    22  
    23  // Builder creates new Map. Each Builder has a unique Scope.
    24  //
    25  // IMPORTANT:  Nodes are hash-consed internally to reduce memory consumption. To
    26  // support hash-consing Builders keep an internal Map of all of the Maps that they
    27  // have created. To GC any of the Maps created by the Builder, all references to
    28  // the Builder must be dropped. This includes MutMaps.
    29  type Builder struct {
    30  	scope Scope
    31  
    32  	// hash-consing maps for each node type.
    33  	empty    *empty
    34  	leaves   map[leaf]*leaf
    35  	branches map[branch]*branch
    36  	// It may be possible to support more types of patricia tries
    37  	// (e.g. non-hash-consed) by making Builder an interface and abstracting
    38  	// the mkLeaf and mkBranch functions.
    39  }
    40  
    41  // NewBuilder creates a new Builder with a unique Scope.
    42  func NewBuilder() *Builder {
    43  	s := newScope()
    44  	return &Builder{
    45  		scope:    s,
    46  		empty:    &empty{s},
    47  		leaves:   make(map[leaf]*leaf),
    48  		branches: make(map[branch]*branch),
    49  	}
    50  }
    51  
    52  func (b *Builder) Scope() Scope { return b.scope }
    53  
    54  // Rescope changes the builder's scope to a new unique Scope.
    55  //
    56  // Any Maps created using the previous scope need to be Cloned
    57  // before any operation.
    58  //
    59  // This makes the old internals of the Builder eligible to be GC'ed.
    60  func (b *Builder) Rescope() {
    61  	s := newScope()
    62  	b.scope = s
    63  	b.empty = &empty{s}
    64  	b.leaves = make(map[leaf]*leaf)
    65  	b.branches = make(map[branch]*branch)
    66  }
    67  
    68  // Empty is the empty map.
    69  func (b *Builder) Empty() Map { return Map{b.Scope(), b.empty} }
    70  
    71  // InsertWith inserts a new association from k to v into the Map m to create a new map
    72  // in the current scope and handle collisions using the collision function c.
    73  //
    74  // This is roughly corresponds to updating a map[uint64]interface{} by:
    75  //   if _, ok := m[k]; ok { m[k] = c(m[k], v} else { m[k] = v}
    76  //
    77  // An insertion or update happened whenever Insert(m, ...) != m .
    78  func (b *Builder) InsertWith(c Collision, m Map, k uint64, v interface{}) Map {
    79  	m = b.Clone(m)
    80  	return Map{b.Scope(), b.insert(c, m.n, b.mkLeaf(key(k), v), false)}
    81  }
    82  
    83  // Inserts a new association from key to value into the Map m to create
    84  // a new map in the current scope.
    85  //
    86  // If there was a previous value mapped by key, keep the previously mapped value.
    87  // This is roughly corresponds to updating a map[uint64]interface{} by:
    88  //   if _, ok := m[k]; ok { m[k] = val }
    89  //
    90  // This is equivalent to b.Merge(m, b.Create({k: v})).
    91  func (b *Builder) Insert(m Map, k uint64, v interface{}) Map {
    92  	return b.InsertWith(TakeLhs, m, k, v)
    93  }
    94  
    95  // Updates a (key, value) in the map. This is roughly corresponds to
    96  // updating a map[uint64]interface{} by:
    97  //   m[key] = val
    98  func (b *Builder) Update(m Map, key uint64, val interface{}) Map {
    99  	return b.InsertWith(TakeRhs, m, key, val)
   100  }
   101  
   102  // Merge two maps lhs and rhs to create a new map in the current scope.
   103  //
   104  // Whenever there is a key in both maps (a collision), the resulting value mapped by
   105  // the key will be `c(lhs[key], rhs[key])`.
   106  func (b *Builder) MergeWith(c Collision, lhs, rhs Map) Map {
   107  	lhs, rhs = b.Clone(lhs), b.Clone(rhs)
   108  	return Map{b.Scope(), b.merge(c, lhs.n, rhs.n)}
   109  }
   110  
   111  // Merge two maps lhs and rhs to create a new map in the current scope.
   112  //
   113  // Whenever there is a key in both maps (a collision), the resulting value mapped by
   114  // the key will be the value in lhs `b.Collision(lhs[key], rhs[key])`.
   115  func (b *Builder) Merge(lhs, rhs Map) Map {
   116  	return b.MergeWith(TakeLhs, lhs, rhs)
   117  }
   118  
   119  // Clone returns a Map that contains the same (key, value) elements
   120  // within b.Scope(), i.e. return m if m.Scope() == b.Scope() or return
   121  // a deep copy of m within b.Scope() otherwise.
   122  func (b *Builder) Clone(m Map) Map {
   123  	if m.Scope() == b.Scope() {
   124  		return m
   125  	} else if m.n == nil {
   126  		return Map{b.Scope(), b.empty}
   127  	}
   128  	return Map{b.Scope(), b.clone(m.n)}
   129  }
   130  func (b *Builder) clone(n node) node {
   131  	switch n := n.(type) {
   132  	case *empty:
   133  		return b.empty
   134  	case *leaf:
   135  		return b.mkLeaf(n.k, n.v)
   136  	case *branch:
   137  		return b.mkBranch(n.prefix, n.branching, b.clone(n.left), b.clone(n.right))
   138  	default:
   139  		panic("unreachable")
   140  	}
   141  }
   142  
   143  // Remove a key from a Map m and return the resulting Map.
   144  func (b *Builder) Remove(m Map, k uint64) Map {
   145  	m = b.Clone(m)
   146  	return Map{b.Scope(), b.remove(m.n, key(k))}
   147  }
   148  
   149  // Intersect Maps lhs and rhs and returns a map with all of the keys in
   150  // both lhs and rhs and the value comes from lhs, i.e.
   151  //   {(k, lhs[k]) | k in lhs, k in rhs}.
   152  func (b *Builder) Intersect(lhs, rhs Map) Map {
   153  	return b.IntersectWith(TakeLhs, lhs, rhs)
   154  }
   155  
   156  // IntersectWith take lhs and rhs and returns the intersection
   157  // with the value coming from the collision function, i.e.
   158  //   {(k, c(lhs[k], rhs[k]) ) | k in lhs, k in rhs}.
   159  // The elements of the resulting map are always { <k, c(lhs[k], rhs[k]) > }
   160  // for each key k that a key in both lhs and rhs.
   161  func (b *Builder) IntersectWith(c Collision, lhs, rhs Map) Map {
   162  	l, r := b.Clone(lhs), b.Clone(rhs)
   163  	return Map{b.Scope(), b.intersect(c, l.n, r.n)}
   164  }
   165  
   166  // MutMap is a convenient wrapper for a Map and a *Builder that will be used to create
   167  // new Maps from it.
   168  type MutMap struct {
   169  	B *Builder
   170  	M Map
   171  }
   172  
   173  // MutEmpty is an empty MutMap for a builder.
   174  func (b *Builder) MutEmpty() MutMap {
   175  	return MutMap{b, b.Empty()}
   176  }
   177  
   178  // Insert an element into the map using the collision function for the builder.
   179  // Returns true if the element was inserted.
   180  func (mm *MutMap) Insert(k uint64, v interface{}) bool {
   181  	old := mm.M
   182  	mm.M = mm.B.Insert(old, k, v)
   183  	return old != mm.M
   184  }
   185  
   186  // Updates an element in the map. Returns true if the map was updated.
   187  func (mm *MutMap) Update(k uint64, v interface{}) bool {
   188  	old := mm.M
   189  	mm.M = mm.B.Update(old, k, v)
   190  	return old != mm.M
   191  }
   192  
   193  // Removes a key from the map. Returns true if the element was removed.
   194  func (mm *MutMap) Remove(k uint64) bool {
   195  	old := mm.M
   196  	mm.M = mm.B.Remove(old, k)
   197  	return old != mm.M
   198  }
   199  
   200  // Merge another map into the current one using the collision function
   201  // for the builder. Returns true if the map changed.
   202  func (mm *MutMap) Merge(other Map) bool {
   203  	old := mm.M
   204  	mm.M = mm.B.Merge(old, other)
   205  	return old != mm.M
   206  }
   207  
   208  // Intersect another map into the current one using the collision function
   209  // for the builder. Returns true if the map changed.
   210  func (mm *MutMap) Intersect(other Map) bool {
   211  	old := mm.M
   212  	mm.M = mm.B.Intersect(old, other)
   213  	return old != mm.M
   214  }
   215  
   216  func (b *Builder) Create(m map[uint64]interface{}) Map {
   217  	var leaves []*leaf
   218  	for k, v := range m {
   219  		leaves = append(leaves, b.mkLeaf(key(k), v))
   220  	}
   221  	return Map{b.Scope(), b.create(leaves)}
   222  }
   223  
   224  // Merge another map into the current one using the collision function
   225  // for the builder. Returns true if the map changed.
   226  func (mm *MutMap) MergeWith(c Collision, other Map) bool {
   227  	old := mm.M
   228  	mm.M = mm.B.MergeWith(c, old, other)
   229  	return old != mm.M
   230  }
   231  
   232  // creates a map for a collection of leaf nodes.
   233  func (b *Builder) create(leaves []*leaf) node {
   234  	n := len(leaves)
   235  	if n == 0 {
   236  		return b.empty
   237  	} else if n == 1 {
   238  		return leaves[0]
   239  	}
   240  	// Note: we can do a more sophisicated algorithm by:
   241  	// - sorting the leaves ahead of time,
   242  	// - taking the prefix and branching bit of the min and max key,
   243  	// - binary searching for the branching bit,
   244  	// - splitting exactly where the branch will be, and
   245  	// - making the branch node for this prefix + branching bit.
   246  	// Skipping until this is a performance bottleneck.
   247  
   248  	m := n / 2 // (n >= 2) ==> 1 <= m < n
   249  	l, r := leaves[:m], leaves[m:]
   250  	return b.merge(nil, b.create(l), b.create(r))
   251  }
   252  
   253  // mkLeaf returns the hash-consed representative of (k, v) in the current scope.
   254  func (b *Builder) mkLeaf(k key, v interface{}) *leaf {
   255  	l := &leaf{k: k, v: v}
   256  	if rep, ok := b.leaves[*l]; ok {
   257  		return rep
   258  	}
   259  	b.leaves[*l] = l
   260  	return l
   261  }
   262  
   263  // mkBranch returns the hash-consed representative of the tuple
   264  //   (prefix, branch, left, right)
   265  // in the current scope.
   266  func (b *Builder) mkBranch(p prefix, bp bitpos, left node, right node) *branch {
   267  	br := &branch{
   268  		sz:        left.size() + right.size(),
   269  		prefix:    p,
   270  		branching: bp,
   271  		left:      left,
   272  		right:     right,
   273  	}
   274  	if rep, ok := b.branches[*br]; ok {
   275  		return rep
   276  	}
   277  	b.branches[*br] = br
   278  	return br
   279  }
   280  
   281  // join two maps with prefixes p0 and p1 that are *known* to disagree.
   282  func (b *Builder) join(p0 prefix, t0 node, p1 prefix, t1 node) *branch {
   283  	m := branchingBit(p0, p1)
   284  	var left, right node
   285  	if zeroBit(p0, m) {
   286  		left, right = t0, t1
   287  	} else {
   288  		left, right = t1, t0
   289  	}
   290  	prefix := mask(p0, m)
   291  	return b.mkBranch(prefix, m, left, right)
   292  }
   293  
   294  // collide two leaves with the same key to create a leaf
   295  // with the collided value.
   296  func (b *Builder) collide(c Collision, left, right *leaf) *leaf {
   297  	if left == right {
   298  		return left // c is idempotent: c(x, x) == x
   299  	}
   300  	val := left.v // keep the left value by default if c is nil
   301  	if c != nil {
   302  		val = c(left.v, right.v)
   303  	}
   304  	switch val {
   305  	case left.v:
   306  		return left
   307  	case right.v:
   308  		return right
   309  	default:
   310  		return b.mkLeaf(left.k, val)
   311  	}
   312  }
   313  
   314  // inserts a leaf l into a map m and returns the resulting map.
   315  // When lhs is true, l is the left hand side in a collision.
   316  // Both l and m are in the current scope.
   317  func (b *Builder) insert(c Collision, m node, l *leaf, lhs bool) node {
   318  	switch m := m.(type) {
   319  	case *empty:
   320  		return l
   321  	case *leaf:
   322  		if m.k == l.k {
   323  			left, right := l, m
   324  			if !lhs {
   325  				left, right = right, left
   326  			}
   327  			return b.collide(c, left, right)
   328  		}
   329  		return b.join(prefix(l.k), l, prefix(m.k), m)
   330  	case *branch:
   331  		// fallthrough
   332  	}
   333  	// m is a branch
   334  	br := m.(*branch)
   335  	if !matchPrefix(prefix(l.k), br.prefix, br.branching) {
   336  		return b.join(prefix(l.k), l, br.prefix, br)
   337  	}
   338  	var left, right node
   339  	if zeroBit(prefix(l.k), br.branching) {
   340  		left, right = b.insert(c, br.left, l, lhs), br.right
   341  	} else {
   342  		left, right = br.left, b.insert(c, br.right, l, lhs)
   343  	}
   344  	if left == br.left && right == br.right {
   345  		return m
   346  	}
   347  	return b.mkBranch(br.prefix, br.branching, left, right)
   348  }
   349  
   350  // merge two maps in the current scope.
   351  func (b *Builder) merge(c Collision, lhs, rhs node) node {
   352  	if lhs == rhs {
   353  		return lhs
   354  	}
   355  	switch lhs := lhs.(type) {
   356  	case *empty:
   357  		return rhs
   358  	case *leaf:
   359  		return b.insert(c, rhs, lhs, true)
   360  	case *branch:
   361  		switch rhs := rhs.(type) {
   362  		case *empty:
   363  			return lhs
   364  		case *leaf:
   365  			return b.insert(c, lhs, rhs, false)
   366  		case *branch:
   367  			// fallthrough
   368  		}
   369  	}
   370  
   371  	// Last remaining case is branch branch merging.
   372  	// For brevity, we adopt the Okasaki and Gill naming conventions
   373  	// for branching and prefixes.
   374  	s, t := lhs.(*branch), rhs.(*branch)
   375  	p, m := s.prefix, s.branching
   376  	q, n := t.prefix, t.branching
   377  
   378  	if m == n && p == q { // prefixes are identical.
   379  		left, right := b.merge(c, s.left, t.left), b.merge(c, s.right, t.right)
   380  		return b.mkBranch(p, m, left, right)
   381  	}
   382  	if !prefixesOverlap(p, m, q, n) {
   383  		return b.join(p, s, q, t) // prefixes are disjoint.
   384  	}
   385  	// prefixesOverlap(p, m, q, n) && !(m ==n && p == q)
   386  	// By prefixesOverlap(...), either:
   387  	//   higher(m, n) && matchPrefix(q, p, m), or
   388  	//   higher(n, m) && matchPrefix(p, q, n)
   389  	// So either s or t may can be merged with one branch or the other.
   390  	switch {
   391  	case ord(m, n) && zeroBit(q, m):
   392  		return b.mkBranch(p, m, b.merge(c, s.left, t), s.right)
   393  	case ord(m, n) && !zeroBit(q, m):
   394  		return b.mkBranch(p, m, s.left, b.merge(c, s.right, t))
   395  	case ord(n, m) && zeroBit(p, n):
   396  		return b.mkBranch(q, n, b.merge(c, s, t.left), t.right)
   397  	default:
   398  		return b.mkBranch(q, n, t.left, b.merge(c, s, t.right))
   399  	}
   400  }
   401  
   402  func (b *Builder) remove(m node, k key) node {
   403  	switch m := m.(type) {
   404  	case *empty:
   405  		return m
   406  	case *leaf:
   407  		if m.k == k {
   408  			return b.empty
   409  		}
   410  		return m
   411  	case *branch:
   412  		// fallthrough
   413  	}
   414  	br := m.(*branch)
   415  	kp := prefix(k)
   416  	if !matchPrefix(kp, br.prefix, br.branching) {
   417  		// The prefix does not match. kp is not in br.
   418  		return br
   419  	}
   420  	// the prefix matches. try to remove from the left or right branch.
   421  	left, right := br.left, br.right
   422  	if zeroBit(kp, br.branching) {
   423  		left = b.remove(left, k) // k may be in the left branch.
   424  	} else {
   425  		right = b.remove(right, k) // k may be in the right branch.
   426  	}
   427  	if left == br.left && right == br.right {
   428  		return br // no update
   429  	} else if _, ok := left.(*empty); ok {
   430  		return right // left updated and is empty.
   431  	} else if _, ok := right.(*empty); ok {
   432  		return left // right updated and is empty.
   433  	}
   434  	// Either left or right updated. Both left and right are not empty.
   435  	// The left and right branches still share the same prefix and disagree
   436  	// on the same branching bit. It is safe to directly create the branch.
   437  	return b.mkBranch(br.prefix, br.branching, left, right)
   438  }
   439  
   440  func (b *Builder) intersect(c Collision, l, r node) node {
   441  	if l == r {
   442  		return l
   443  	}
   444  	switch l := l.(type) {
   445  	case *empty:
   446  		return b.empty
   447  	case *leaf:
   448  		if rleaf := r.find(l.k); rleaf != nil {
   449  			return b.collide(c, l, rleaf)
   450  		}
   451  		return b.empty
   452  	case *branch:
   453  		switch r := r.(type) {
   454  		case *empty:
   455  			return b.empty
   456  		case *leaf:
   457  			if lleaf := l.find(r.k); lleaf != nil {
   458  				return b.collide(c, lleaf, r)
   459  			}
   460  			return b.empty
   461  		case *branch:
   462  			// fallthrough
   463  		}
   464  	}
   465  	// Last remaining case is branch branch intersection.
   466  	s, t := l.(*branch), r.(*branch)
   467  	p, m := s.prefix, s.branching
   468  	q, n := t.prefix, t.branching
   469  
   470  	if m == n && p == q {
   471  		// prefixes are identical.
   472  		left, right := b.intersect(c, s.left, t.left), b.intersect(c, s.right, t.right)
   473  		if _, ok := left.(*empty); ok {
   474  			return right
   475  		} else if _, ok := right.(*empty); ok {
   476  			return left
   477  		}
   478  		// The left and right branches are both non-empty.
   479  		// They still share the same prefix and disagree on the same branching bit.
   480  		// It is safe to directly create the branch.
   481  		return b.mkBranch(p, m, left, right)
   482  	}
   483  
   484  	if !prefixesOverlap(p, m, q, n) {
   485  		return b.empty // The prefixes share no keys.
   486  	}
   487  	// prefixesOverlap(p, m, q, n) && !(m ==n && p == q)
   488  	// By prefixesOverlap(...), either:
   489  	//   ord(m, n) && matchPrefix(q, p, m), or
   490  	//   ord(n, m) && matchPrefix(p, q, n)
   491  	// So either s or t may be a strict subtree of the other.
   492  	var lhs, rhs node
   493  	switch {
   494  	case ord(m, n) && zeroBit(q, m):
   495  		lhs, rhs = s.left, t
   496  	case ord(m, n) && !zeroBit(q, m):
   497  		lhs, rhs = s.right, t
   498  	case ord(n, m) && zeroBit(p, n):
   499  		lhs, rhs = s, t.left
   500  	default:
   501  		lhs, rhs = s, t.right
   502  	}
   503  	return b.intersect(c, lhs, rhs)
   504  }