@@ -9,10 +9,12 @@ import (
99)
1010
1111// Map implements a map that keeps the item order.
12+ // It preserves the insertion order of keys for both JSON unmarshalling
13+ // and manual operations.
1214type Map struct {
13- // Data holds the map entries in unsorted order .
15+ // Data holds the map entries with their sequence indices .
1416 Data map [string ]Entry
15- // Keys contains the map keys in sorted order.
17+ // Keys contains the map keys in insertion order.
1618 Keys []string
1719}
1820
@@ -21,9 +23,88 @@ func (m *Map) Len() int {
2123 return len (m .Keys )
2224}
2325
26+ // Get retrieves the value for the given key.
27+ // Returns the value and true if the key exists, or nil and false otherwise.
28+ func (m * Map ) Get (key string ) (any , bool ) {
29+ if m .Data == nil {
30+ return nil , false
31+ }
32+ entry , exists := m .Data [key ]
33+ if ! exists {
34+ return nil , false
35+ }
36+ return entry .Value , true
37+ }
38+
39+ // Set adds or updates a key-value pair in the map.
40+ // If the key already exists, its value is updated without changing position.
41+ // If the key is new, it is appended to the end of the insertion order.
42+ func (m * Map ) Set (key string , value any ) {
43+ if m .Data == nil {
44+ m .Data = make (map [string ]Entry )
45+ }
46+
47+ if _ , exists := m .Data [key ]; ! exists {
48+ m .Keys = append (m .Keys , key )
49+ }
50+
51+ m .Data [key ] = Entry {
52+ index : nextSequence (),
53+ Value : value ,
54+ }
55+ }
56+
57+ // Delete removes a key-value pair from the map.
58+ // Returns true if the key existed and was deleted, false otherwise.
59+ //
60+ // Performance note: This operation is O(n) where n is the number of keys,
61+ // as it requires searching through the Keys slice to find and remove the key.
62+ func (m * Map ) Delete (key string ) bool {
63+ if m .Data == nil {
64+ return false
65+ }
66+
67+ if _ , exists := m .Data [key ]; ! exists {
68+ return false
69+ }
70+
71+ delete (m .Data , key )
72+
73+ for i , k := range m .Keys {
74+ if k == key {
75+ m .Keys = append (m .Keys [:i ], m .Keys [i + 1 :]... )
76+ break
77+ }
78+ }
79+
80+ return true
81+ }
82+
83+ // GetAndDelete retrieves and removes a key in one operation.
84+ // Returns the value and true if the key existed, or nil and false otherwise.
85+ //
86+ // Performance note: This operation is O(n) due to the underlying Delete operation.
87+ func (m * Map ) GetAndDelete (key string ) (value any , loaded bool ) {
88+ value , loaded = m .Get (key )
89+ if loaded {
90+ m .Delete (key )
91+ }
92+ return value , loaded
93+ }
94+
95+ // Clear removes all entries from the map, resulting in an empty map.
96+ func (m * Map ) Clear () {
97+ m .Data = make (map [string ]Entry )
98+ m .Keys = nil
99+ }
100+
24101// Range calls f sequentially for each key and value present in the map.
25102// If f returns false, range stops the iteration.
26103func (m * Map ) Range (f func (key string , value any ) bool ) {
104+ if m .Data == nil || len (m .Keys ) == 0 {
105+ return
106+ }
107+
27108 for _ , key := range m .Keys {
28109 entry := m .Data [key ]
29110 if ! f (key , entry .Value ) {
@@ -44,31 +125,41 @@ func (m *Map) UnmarshalJSON(b []byte) error {
44125
45126// MarshalJSON implements the json.Marshaler interface.
46127func (m * Map ) MarshalJSON () ([]byte , error ) {
47- var buf bytes.Buffer
128+ if m == nil || len (m .Keys ) == 0 {
129+ return []byte ("{}" ), nil
130+ }
131+
132+ buf := bytes .NewBuffer (make ([]byte , 0 , len (m .Keys )* 20 ))
48133 buf .WriteString ("{" )
49134
135+ lastIdx := len (m .Keys ) - 1
50136 for i , key := range m .Keys {
51- buf .WriteString (fmt .Sprintf ("%q:" , key ))
137+ keyData , err := json .Marshal (key )
138+ if err != nil {
139+ return nil , fmt .Errorf ("marshalling key %q: %w" , key , err )
140+ }
141+ buf .Write (keyData )
142+ buf .WriteByte (':' )
52143
53144 value := m .Data [key ].Value
54145 b , err := json .Marshal (value )
55146 if err != nil {
56- return nil , fmt .Errorf ("marshalling entry: %w" , err )
147+ return nil , fmt .Errorf ("marshalling entry for key %q : %w" , key , err )
57148 }
58149 buf .Write (b )
59150
60- if i < len ( m . Keys ) - 1 {
61- buf .WriteString ( "," )
151+ if i < lastIdx {
152+ buf .WriteByte ( ',' )
62153 }
63154 }
64155
65- buf .WriteString ( "}" )
156+ buf .WriteByte ( '}' )
66157 return buf .Bytes (), nil
67158}
68159
69- // rebuildKeys build the sorted keys slice.
160+ // rebuildKeys builds the keys slice sorted by insertion order .
70161func (m * Map ) rebuildKeys () {
71- m .Keys = []string {}
162+ m .Keys = make ( []string , 0 , len ( m . Data ))
72163 for name := range m .Data {
73164 m .Keys = append (m .Keys , name )
74165 }
0 commit comments