github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/maps/treemap/treemap.go (about)

     1  // Package treemap implements a map backed by red-black tree.
     2  //
     3  // Elements are ordered by key in the map.
     4  //
     5  // Structure is not thread safe.
     6  //
     7  // Reference: http://en.wikipedia.org/wiki/Associative_array
     8  package treemap
     9  
    10  import (
    11  	"fmt"
    12  	"strings"
    13  
    14  	"github.com/songzhibin97/go-baseutils/base/bcomparator"
    15  	"github.com/songzhibin97/go-baseutils/structure/maps"
    16  	"github.com/songzhibin97/go-baseutils/structure/trees/redblacktree"
    17  )
    18  
    19  // Assert Map implementation
    20  var _ maps.Map[int, any] = (*Map[int, any])(nil)
    21  
    22  // Map holds the elements in a red-black tree
    23  type Map[K, V any] struct {
    24  	tree  *redblacktree.Tree[K, V]
    25  	zeroK K
    26  	zeroV V
    27  }
    28  
    29  // NewWith instantiates a tree map with the custom comparator.
    30  func NewWith[K, V any](comparator bcomparator.Comparator[K]) *Map[K, V] {
    31  	return &Map[K, V]{tree: redblacktree.NewWith[K, V](comparator)}
    32  }
    33  
    34  // NewWithIntComparator instantiates a tree map with the IntComparator, i.e. keys are of type int.
    35  func NewWithIntComparator[V any]() *Map[int, V] {
    36  	return &Map[int, V]{tree: redblacktree.NewWithIntComparator[V]()}
    37  }
    38  
    39  // NewWithStringComparator instantiates a tree map with the StringComparator, i.e. keys are of type string.
    40  func NewWithStringComparator[V any]() *Map[string, V] {
    41  	return &Map[string, V]{tree: redblacktree.NewWithStringComparator[V]()}
    42  }
    43  
    44  // Put inserts key-value pair into the map.
    45  // Key should adhere to the comparator's type assertion, otherwise method panics.
    46  func (m *Map[K, V]) Put(key K, value V) {
    47  	m.tree.Put(key, value)
    48  }
    49  
    50  // Get searches the element in the map by key and returns its value or nil if key is not found in tree.
    51  // Second return parameter is true if key was found, otherwise false.
    52  // Key should adhere to the comparator's type assertion, otherwise method panics.
    53  func (m *Map[K, V]) Get(key K) (value V, found bool) {
    54  	return m.tree.Get(key)
    55  }
    56  
    57  // Remove removes the element from the map by key.
    58  // Key should adhere to the comparator's type assertion, otherwise method panics.
    59  func (m *Map[K, V]) Remove(key K) {
    60  	m.tree.Remove(key)
    61  }
    62  
    63  // Empty returns true if map does not contain any elements
    64  func (m *Map[K, V]) Empty() bool {
    65  	return m.tree.Empty()
    66  }
    67  
    68  // Size returns number of elements in the map.
    69  func (m *Map[K, V]) Size() int {
    70  	return m.tree.Size()
    71  }
    72  
    73  // Keys returns all keys in-order
    74  func (m *Map[K, V]) Keys() []K {
    75  	return m.tree.Keys()
    76  }
    77  
    78  // Values returns all values in-order based on the key.
    79  func (m *Map[K, V]) Values() []V {
    80  	return m.tree.Values()
    81  }
    82  
    83  // Clear removes all elements from the map.
    84  func (m *Map[K, V]) Clear() {
    85  	m.tree.Clear()
    86  }
    87  
    88  // Min returns the minimum key and its value from the tree map.
    89  // Returns nil, nil if map is empty.
    90  func (m *Map[K, V]) Min() (key K, value V) {
    91  	if node := m.tree.Left(); node != nil {
    92  		return node.Key, node.Value
    93  	}
    94  	return m.zeroK, m.zeroV
    95  }
    96  
    97  // Max returns the maximum key and its value from the tree map.
    98  // Returns nil, nil if map is empty.
    99  func (m *Map[K, V]) Max() (key K, value V) {
   100  	if node := m.tree.Right(); node != nil {
   101  		return node.Key, node.Value
   102  	}
   103  	return m.zeroK, m.zeroV
   104  }
   105  
   106  // Floor finds the floor key-value pair for the input key.
   107  // In case that no floor is found, then both returned values will be nil.
   108  // It's generally enough to check the first value (key) for nil, which determines if floor was found.
   109  //
   110  // Floor key is defined as the largest key that is smaller than or equal to the given key.
   111  // A floor key may not be found, either because the map is empty, or because
   112  // all keys in the map are larger than the given key.
   113  //
   114  // Key should adhere to the comparator's type assertion, otherwise method panics.
   115  func (m *Map[K, V]) Floor(key K) (foundkey K, foundvalue V) {
   116  	node, found := m.tree.Floor(key)
   117  	if found {
   118  		return node.Key, node.Value
   119  	}
   120  	return m.zeroK, m.zeroV
   121  }
   122  
   123  // Ceiling finds the ceiling key-value pair for the input key.
   124  // In case that no ceiling is found, then both returned values will be nil.
   125  // It's generally enough to check the first value (key) for nil, which determines if ceiling was found.
   126  //
   127  // Ceiling key is defined as the smallest key that is larger than or equal to the given key.
   128  // A ceiling key may not be found, either because the map is empty, or because
   129  // all keys in the map are smaller than the given key.
   130  //
   131  // Key should adhere to the comparator's type assertion, otherwise method panics.
   132  func (m *Map[K, V]) Ceiling(key K) (foundkey K, foundvalue V) {
   133  	node, found := m.tree.Ceiling(key)
   134  	if found {
   135  		return node.Key, node.Value
   136  	}
   137  	return m.zeroK, m.zeroV
   138  }
   139  
   140  // String returns a string representation of container
   141  func (m *Map[K, V]) String() string {
   142  	bf := strings.Builder{}
   143  	bf.WriteString("TreeMap\nmap[")
   144  	it := m.Iterator()
   145  	for it.Next() {
   146  		bf.WriteString(fmt.Sprintf("(%v:%v) ", it.Key(), it.Value()))
   147  	}
   148  	bf.WriteString("]")
   149  	return bf.String()
   150  }
   151  
   152  // UnmarshalJSON @implements json.Unmarshaler
   153  func (m *Map[K, V]) UnmarshalJSON(bytes []byte) error {
   154  	return m.tree.UnmarshalJSON(bytes)
   155  }
   156  
   157  // MarshalJSON @implements json.Marshaler
   158  func (m *Map[K, V]) MarshalJSON() ([]byte, error) {
   159  	return m.tree.MarshalJSON()
   160  }