github.com/tursom/GoCollections@v0.3.10/collections/Map.go (about)

     1  /*
     2   * Copyright (c) 2022 tursom. All rights reserved.
     3   * Use of this source code is governed by a GPL-3
     4   * license that can be found in the LICENSE file.
     5   */
     6  
     7  package collections
     8  
     9  import (
    10  	"fmt"
    11  	"strings"
    12  
    13  	"github.com/tursom/GoCollections/exceptions"
    14  	"github.com/tursom/GoCollections/lang"
    15  )
    16  
    17  type (
    18  	MapLooper[K lang.Object, V any] interface {
    19  		Loop(func(K, V) exceptions.Exception) exceptions.Exception
    20  	}
    21  
    22  	Map[K lang.Object, V any] interface {
    23  		MapLooper[K, V]
    24  		Get(k K) (V, bool, exceptions.Exception)
    25  	}
    26  
    27  	MutableMap[K lang.Object, V any] interface {
    28  		Map[K, V]
    29  		Put(k K, v V) (bool, exceptions.Exception)
    30  		Remove(k K) (V, bool, exceptions.Exception)
    31  	}
    32  
    33  	MapNodeFinder[K lang.Object, V any] interface {
    34  		findNode(k K, createIfNotExist bool) (node, prev MapNode[K, V])
    35  	}
    36  
    37  	MapSlotFinder[K lang.Object, V any] interface {
    38  		FindSlot(k K) (root MapNode[K, V])
    39  	}
    40  
    41  	MapNode[K lang.Object, V any] interface {
    42  		GetKey() K
    43  		GetValue() V
    44  		SetValue(value V)
    45  		CreateNext(key K) MapNode[K, V]
    46  		GetNext() MapNode[K, V]
    47  		RemoveNext()
    48  	}
    49  
    50  	SimpleMapNode[K lang.Object, V any] struct {
    51  		lang.BaseObject
    52  		key   K
    53  		value V
    54  		next  *SimpleMapNode[K, V]
    55  	}
    56  
    57  	NodeMap[K lang.Object, V any] struct {
    58  		lang.BaseObject
    59  		MapNodeFinder MapNodeFinder[K, V]
    60  	}
    61  
    62  	MapNodeFinderBySlot[K lang.Object, V any] struct {
    63  		lang.BaseObject
    64  		slotFinder MapSlotFinder[K, V]
    65  	}
    66  )
    67  
    68  func NewMapNodeFinderBySlot[K lang.Object, V any](slotFinder MapSlotFinder[K, V]) MapNodeFinder[K, V] {
    69  	return &MapNodeFinderBySlot[K, V]{slotFinder: slotFinder}
    70  }
    71  
    72  func MapToString[K lang.Object, V any](m MapLooper[K, V]) lang.String {
    73  	builder := strings.Builder{}
    74  	builder.WriteString("{")
    75  	_ = m.Loop(func(k K, v V) exceptions.Exception {
    76  		if builder.Len() != 1 {
    77  			builder.WriteString(", ")
    78  		}
    79  		builder.WriteString(k.String())
    80  		builder.WriteString(": ")
    81  		if ov, ok := lang.TryCast[lang.Object](v); ok {
    82  			builder.WriteString(ov.String())
    83  		} else {
    84  			builder.WriteString(fmt.Sprint(v))
    85  		}
    86  		return nil
    87  	})
    88  	builder.WriteString("}")
    89  	return lang.NewString(builder.String())
    90  }
    91  
    92  func (g *NodeMap[K, V]) findNode(k K, createIfNotExist bool) (node, prev MapNode[K, V]) {
    93  	return g.MapNodeFinder.findNode(k, createIfNotExist)
    94  }
    95  
    96  func (g *NodeMap[K, V]) Put(k K, v V) (bool, exceptions.Exception) {
    97  	node, _ := g.findNode(k, true)
    98  	node.SetValue(v)
    99  	return true, nil
   100  }
   101  
   102  func (g *NodeMap[K, V]) Get(k K) (V, bool, exceptions.Exception) {
   103  	node, _ := g.findNode(k, false)
   104  	if node == nil {
   105  		return g.nil()
   106  	} else {
   107  		return node.GetValue(), true, nil
   108  	}
   109  }
   110  
   111  func (g *NodeMap[K, V]) Remove(k K) (V, bool, exceptions.Exception) {
   112  	node, prev := g.findNode(k, false)
   113  	if node == nil {
   114  		return g.nil()
   115  	} else {
   116  		if prev != nil {
   117  			prev.RemoveNext()
   118  		}
   119  		return node.GetValue(), true, nil
   120  	}
   121  }
   122  
   123  func (g *NodeMap[K, V]) nil() (V, bool, exceptions.Exception) {
   124  	return lang.Nil[V](), false, nil
   125  }
   126  
   127  func (m *MapNodeFinderBySlot[K, V]) findNode(k K, createIfNotExist bool) (node, prev MapNode[K, V]) {
   128  	prev = m.slotFinder.FindSlot(k)
   129  	if prev != nil {
   130  		node = prev.GetNext()
   131  		for node != nil {
   132  			if node.GetKey().Equals(k) {
   133  				return
   134  			}
   135  			prev = node
   136  			node = node.GetNext()
   137  		}
   138  	}
   139  	if createIfNotExist {
   140  		node = prev.CreateNext(k)
   141  	}
   142  	return
   143  }
   144  
   145  func (s *SimpleMapNode[K, V]) String() string {
   146  	return "SimpleMapNode{key: " + s.key.String() + ", value: " + fmt.Sprint(s.value) + "}"
   147  }
   148  
   149  func (s *SimpleMapNode[K, V]) GetKey() K {
   150  	return s.key
   151  }
   152  
   153  func (s *SimpleMapNode[K, V]) GetValue() V {
   154  	return s.value
   155  }
   156  
   157  func (s *SimpleMapNode[K, V]) SetValue(value V) {
   158  	s.value = value
   159  }
   160  
   161  func (s *SimpleMapNode[K, V]) CreateNext(key K) MapNode[K, V] {
   162  	s.next = &SimpleMapNode[K, V]{key: key, next: s.next}
   163  	return s.next
   164  }
   165  
   166  func (s *SimpleMapNode[K, V]) GetNext() MapNode[K, V] {
   167  	if s.next == nil {
   168  		return nil
   169  	}
   170  	return s.next
   171  }
   172  
   173  func (s *SimpleMapNode[K, V]) RemoveNext() {
   174  	if s.next != nil {
   175  		s.next = s.next.next
   176  	}
   177  }