gitee.com/quant1x/gox@v1.21.2/util/linkedhashmap/linkedhashmap.go (about) 1 // Copyright (c) 2015, Emir Pasic. 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 linkedhashmap is a map that preserves insertion-order. 6 // 7 // It is backed by a hash table to store values and doubly-linked list to store ordering. 8 // 9 // Structure is not thread safe. 10 // 11 // Reference: http://en.wikipedia.org/wiki/Associative_array 12 package linkedhashmap 13 14 import ( 15 "fmt" 16 "gitee.com/quant1x/gox/util/doublylinkedlist" 17 "gitee.com/quant1x/gox/util/internal" 18 "strings" 19 ) 20 21 func assertMapImplementation() { 22 var _ internal.Map = (*Map)(nil) 23 } 24 25 // Map holds the elements in a red-black tree 26 type Map struct { 27 table map[interface{}]interface{} 28 ordering *doublylinkedlist.List 29 } 30 31 // New instantiates a linked-hash-map. 32 func New() *Map { 33 return &Map{ 34 table: make(map[interface{}]interface{}), 35 ordering: doublylinkedlist.New(), 36 } 37 } 38 39 // Put inserts key-value pair into the map. 40 // Key should adhere to the comparator's type assertion, otherwise method panics. 41 func (m *Map) Put(key interface{}, value interface{}) { 42 if _, contains := m.table[key]; !contains { 43 m.ordering.Append(key) 44 } 45 m.table[key] = value 46 } 47 48 // Get searches the element in the map by key and returns its value or nil if key is not found in tree. 49 // Second return parameter is true if key was found, otherwise false. 50 // Key should adhere to the comparator's type assertion, otherwise method panics. 51 func (m *Map) Get(key interface{}) (value interface{}, found bool) { 52 value = m.table[key] 53 found = value != nil 54 return 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) Remove(key interface{}) { 60 if _, contains := m.table[key]; contains { 61 delete(m.table, key) 62 index := m.ordering.IndexOf(key) 63 m.ordering.Remove(index) 64 } 65 } 66 67 // Empty returns true if map does not contain any elements 68 func (m *Map) Empty() bool { 69 return m.Size() == 0 70 } 71 72 // Size returns number of elements in the map. 73 func (m *Map) Size() int { 74 return m.ordering.Size() 75 } 76 77 // Keys returns all keys in-order 78 func (m *Map) Keys() []interface{} { 79 return m.ordering.Values() 80 } 81 82 // Values returns all values in-order based on the key. 83 func (m *Map) Values() []interface{} { 84 values := make([]interface{}, m.Size()) 85 count := 0 86 it := m.Iterator() 87 for it.Next() { 88 values[count] = it.Value() 89 count++ 90 } 91 return values 92 } 93 94 // Clear removes all elements from the map. 95 func (m *Map) Clear() { 96 m.table = make(map[interface{}]interface{}) 97 m.ordering.Clear() 98 } 99 100 // String returns a string representation of container 101 func (m *Map) String() string { 102 str := "LinkedHashMap\nmap[" 103 it := m.Iterator() 104 for it.Next() { 105 str += fmt.Sprintf("%v:%v ", it.Key(), it.Value()) 106 } 107 return strings.TrimRight(str, " ") + "]" 108 109 }