@@ -87,6 +87,45 @@ func TestPutLocation(t *testing.T) {
8787 require .Equal (t , indicesLen , stack .LocationIndices ().Len ())
8888}
8989
90+ func TestSetLocation (t * testing.T ) {
91+ table := NewLocationSlice ()
92+ l := NewLocation ()
93+ l .SetAddress (1 )
94+ l2 := NewLocation ()
95+ l2 .SetAddress (2 )
96+
97+ // Put a first value
98+ idx , err := SetLocation (table , l )
99+ require .NoError (t , err )
100+ assert .Equal (t , 1 , table .Len ())
101+ assert .Equal (t , int32 (0 ), idx )
102+
103+ // Put the same string
104+ // This should be a no-op.
105+ idx , err = SetLocation (table , l )
106+ require .NoError (t , err )
107+ assert .Equal (t , 1 , table .Len ())
108+ assert .Equal (t , int32 (0 ), idx )
109+
110+ // Set a new value
111+ // This sets the index and adds to the table.
112+ idx , err = SetLocation (table , l2 )
113+ require .NoError (t , err )
114+ assert .Equal (t , 2 , table .Len ())
115+ assert .Equal (t , int32 (table .Len ()- 1 ), idx ) //nolint:gosec // G115
116+
117+ // Set an existing value
118+ idx , err = SetLocation (table , l )
119+ require .NoError (t , err )
120+ assert .Equal (t , 2 , table .Len ())
121+ assert .Equal (t , int32 (0 ), idx )
122+ // Set another existing value
123+ idx , err = SetLocation (table , l2 )
124+ require .NoError (t , err )
125+ assert .Equal (t , 2 , table .Len ())
126+ assert .Equal (t , int32 (table .Len ()- 1 ), idx ) //nolint:gosec // G115
127+ }
128+
90129func BenchmarkFromLocationIndices (b * testing.B ) {
91130 table := NewLocationSlice ()
92131
@@ -172,3 +211,72 @@ func BenchmarkPutLocation(b *testing.B) {
172211 })
173212 }
174213}
214+
215+ func BenchmarkSetLocation (b * testing.B ) {
216+ for _ , bb := range []struct {
217+ name string
218+ location Location
219+
220+ runBefore func (* testing.B , LocationSlice )
221+ }{
222+ {
223+ name : "with a new location" ,
224+ location : NewLocation (),
225+ },
226+ {
227+ name : "with an existing location" ,
228+ location : func () Location {
229+ l := NewLocation ()
230+ l .SetAddress (1 )
231+ return l
232+ }(),
233+
234+ runBefore : func (_ * testing.B , table LocationSlice ) {
235+ l := table .AppendEmpty ()
236+ l .SetAddress (1 )
237+ },
238+ },
239+ {
240+ name : "with a duplicate location" ,
241+ location : NewLocation (),
242+
243+ runBefore : func (_ * testing.B , table LocationSlice ) {
244+ _ , err := SetLocation (table , NewLocation ())
245+ require .NoError (b , err )
246+ },
247+ },
248+ {
249+ name : "with a hundred locations to loop through" ,
250+ location : func () Location {
251+ l := NewLocation ()
252+ l .SetMappingIndex (1 )
253+ return l
254+ }(),
255+
256+ runBefore : func (_ * testing.B , table LocationSlice ) {
257+ for i := range 100 {
258+ l := table .AppendEmpty ()
259+ l .SetAddress (uint64 (i )) //nolint:gosec // overflow checked
260+ }
261+
262+ l := table .AppendEmpty ()
263+ l .SetMappingIndex (1 )
264+ },
265+ },
266+ } {
267+ b .Run (bb .name , func (b * testing.B ) {
268+ table := NewLocationSlice ()
269+
270+ if bb .runBefore != nil {
271+ bb .runBefore (b , table )
272+ }
273+
274+ b .ResetTimer ()
275+ b .ReportAllocs ()
276+
277+ for b .Loop () {
278+ _ , _ = SetLocation (table , bb .location )
279+ }
280+ })
281+ }
282+ }
0 commit comments