github.com/onflow/atree@v0.6.0/cmd/stress/utils.go (about)

     1  /*
     2   * Atree - Scalable Arrays and Ordered Maps
     3   *
     4   * Copyright 2021 Dapper Labs, Inc.
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package main
    20  
    21  import (
    22  	"fmt"
    23  	"math/rand"
    24  	"reflect"
    25  	"time"
    26  
    27  	"github.com/onflow/atree"
    28  )
    29  
    30  const (
    31  	maxNestedLevels    = 5
    32  	maxNestedArraySize = 50
    33  	maxNestedMapSize   = 50
    34  )
    35  
    36  const (
    37  	uint8Type int = iota
    38  	uint16Type
    39  	uint32Type
    40  	uint64Type
    41  	smallStringType
    42  	largeStringType
    43  	arrayType
    44  	mapType
    45  	maxValueType
    46  )
    47  
    48  var (
    49  	letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    50  
    51  	r *rand.Rand
    52  )
    53  
    54  func newRand(seed int64) *rand.Rand {
    55  	if seed == 0 {
    56  		seed = time.Now().UnixNano()
    57  	}
    58  
    59  	fmt.Printf("rand seed 0x%x\n", seed)
    60  	return rand.New(rand.NewSource(seed))
    61  }
    62  
    63  func randStr(n int) string {
    64  	runes := make([]rune, n)
    65  	for i := range runes {
    66  		runes[i] = letters[r.Intn(len(letters))]
    67  	}
    68  	return string(runes)
    69  }
    70  
    71  func generateValue(storage *atree.PersistentSlabStorage, address atree.Address, valueType int, nestedLevels int) (atree.Value, error) {
    72  	switch valueType {
    73  	case uint8Type:
    74  		return Uint8Value(r.Intn(255)), nil
    75  	case uint16Type:
    76  		return Uint16Value(r.Intn(6535)), nil
    77  	case uint32Type:
    78  		return Uint32Value(r.Intn(4294967295)), nil
    79  	case uint64Type:
    80  		return Uint64Value(r.Intn(1844674407370955161)), nil
    81  	case smallStringType:
    82  		slen := r.Intn(125)
    83  		return NewStringValue(randStr(slen)), nil
    84  	case largeStringType:
    85  		slen := r.Intn(125) + 1024
    86  		return NewStringValue(randStr(slen)), nil
    87  	case arrayType:
    88  		length := r.Intn(maxNestedArraySize)
    89  		return newArray(storage, address, length, nestedLevels)
    90  	case mapType:
    91  		length := r.Intn(maxNestedMapSize)
    92  		return newMap(storage, address, length, nestedLevels)
    93  	default:
    94  		return Uint8Value(r.Intn(255)), nil
    95  	}
    96  }
    97  
    98  func randomKey() (atree.Value, error) {
    99  	t := r.Intn(largeStringType + 1)
   100  	return generateValue(nil, atree.Address{}, t, 0)
   101  }
   102  
   103  func randomValue(storage *atree.PersistentSlabStorage, address atree.Address, nestedLevels int) (atree.Value, error) {
   104  	var t int
   105  	if nestedLevels <= 0 {
   106  		t = r.Intn(largeStringType + 1)
   107  	} else {
   108  		t = r.Intn(maxValueType)
   109  	}
   110  	return generateValue(storage, address, t, nestedLevels)
   111  }
   112  
   113  func copyValue(storage *atree.PersistentSlabStorage, address atree.Address, value atree.Value) (atree.Value, error) {
   114  	switch v := value.(type) {
   115  	case Uint8Value:
   116  		return Uint8Value(uint8(v)), nil
   117  	case Uint16Value:
   118  		return Uint16Value(uint16(v)), nil
   119  	case Uint32Value:
   120  		return Uint32Value(uint32(v)), nil
   121  	case Uint64Value:
   122  		return Uint64Value(uint64(v)), nil
   123  	case StringValue:
   124  		return NewStringValue(v.str), nil
   125  	case *atree.Array:
   126  		return copyArray(storage, address, v)
   127  	case *atree.OrderedMap:
   128  		return copyMap(storage, address, v)
   129  	default:
   130  		return nil, fmt.Errorf("failed to copy value: value type %T isn't supported", v)
   131  	}
   132  }
   133  
   134  func copyArray(storage *atree.PersistentSlabStorage, address atree.Address, array *atree.Array) (*atree.Array, error) {
   135  	iterator, err := array.Iterator()
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  	return atree.NewArrayFromBatchData(storage, address, array.Type(), func() (atree.Value, error) {
   140  		v, err := iterator.Next()
   141  		if err != nil {
   142  			return nil, err
   143  		}
   144  		if v == nil {
   145  			return nil, nil
   146  		}
   147  		return copyValue(storage, address, v)
   148  	})
   149  }
   150  
   151  func copyMap(storage *atree.PersistentSlabStorage, address atree.Address, m *atree.OrderedMap) (*atree.OrderedMap, error) {
   152  	iterator, err := m.Iterator()
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  	return atree.NewMapFromBatchData(
   157  		storage,
   158  		address,
   159  		atree.NewDefaultDigesterBuilder(),
   160  		m.Type(),
   161  		compare,
   162  		hashInputProvider,
   163  		m.Seed(),
   164  		func() (atree.Value, atree.Value, error) {
   165  			k, v, err := iterator.Next()
   166  			if err != nil {
   167  				return nil, nil, err
   168  			}
   169  			if k == nil {
   170  				return nil, nil, nil
   171  			}
   172  			copiedKey, err := copyValue(storage, address, k)
   173  			if err != nil {
   174  				return nil, nil, err
   175  			}
   176  			copiedValue, err := copyValue(storage, address, v)
   177  			if err != nil {
   178  				return nil, nil, err
   179  			}
   180  			return copiedKey, copiedValue, nil
   181  		})
   182  }
   183  
   184  func removeValue(storage *atree.PersistentSlabStorage, value atree.Value) error {
   185  	switch v := value.(type) {
   186  	case *atree.Array:
   187  		return removeStorable(storage, atree.StorageIDStorable(v.StorageID()))
   188  	case *atree.OrderedMap:
   189  		return removeStorable(storage, atree.StorageIDStorable(v.StorageID()))
   190  	}
   191  	return nil
   192  }
   193  
   194  func removeStorable(storage *atree.PersistentSlabStorage, storable atree.Storable) error {
   195  	sid, ok := storable.(atree.StorageIDStorable)
   196  	if !ok {
   197  		return nil
   198  	}
   199  
   200  	id := atree.StorageID(sid)
   201  
   202  	value, err := storable.StoredValue(storage)
   203  	if err != nil {
   204  		return err
   205  	}
   206  
   207  	switch v := value.(type) {
   208  	case StringValue:
   209  		return storage.Remove(id)
   210  	case *atree.Array:
   211  		err := v.PopIterate(func(storable atree.Storable) {
   212  			_ = removeStorable(storage, storable)
   213  		})
   214  		if err != nil {
   215  			return err
   216  		}
   217  		return storage.Remove(id)
   218  
   219  	case *atree.OrderedMap:
   220  		err := v.PopIterate(func(keyStorable atree.Storable, valueStorable atree.Storable) {
   221  			_ = removeStorable(storage, keyStorable)
   222  			_ = removeStorable(storage, valueStorable)
   223  		})
   224  		if err != nil {
   225  			return err
   226  		}
   227  		return storage.Remove(id)
   228  
   229  	default:
   230  		return fmt.Errorf("failed to remove storable: storable type %T isn't supported", v)
   231  	}
   232  }
   233  
   234  func valueEqual(a atree.Value, b atree.Value) error {
   235  	switch a.(type) {
   236  	case *atree.Array:
   237  		return arrayEqual(a, b)
   238  	case *atree.OrderedMap:
   239  		return mapEqual(a, b)
   240  	default:
   241  		if !reflect.DeepEqual(a, b) {
   242  			return fmt.Errorf("value %s (%T) != value %s (%T)", a, a, b, b)
   243  		}
   244  	}
   245  	return nil
   246  }
   247  
   248  func arrayEqual(a atree.Value, b atree.Value) error {
   249  	array1, ok := a.(*atree.Array)
   250  	if !ok {
   251  		return fmt.Errorf("value %s type is %T, want *atree.Array", a, a)
   252  	}
   253  
   254  	array2, ok := b.(*atree.Array)
   255  	if !ok {
   256  		return fmt.Errorf("value %s type is %T, want *atree.Array", b, b)
   257  	}
   258  
   259  	if array1.Count() != array2.Count() {
   260  		return fmt.Errorf("array %s count %d != array %s count %d", array1, array1.Count(), array2, array2.Count())
   261  	}
   262  
   263  	iterator1, err := array1.Iterator()
   264  	if err != nil {
   265  		return fmt.Errorf("failed to get array1 iterator: %w", err)
   266  	}
   267  
   268  	iterator2, err := array2.Iterator()
   269  	if err != nil {
   270  		return fmt.Errorf("failed to get array2 iterator: %w", err)
   271  	}
   272  
   273  	for {
   274  		value1, err := iterator1.Next()
   275  		if err != nil {
   276  			return fmt.Errorf("iterator1.Next() error: %w", err)
   277  		}
   278  
   279  		value2, err := iterator2.Next()
   280  		if err != nil {
   281  			return fmt.Errorf("iterator2.Next() error: %w", err)
   282  		}
   283  
   284  		err = valueEqual(value1, value2)
   285  		if err != nil {
   286  			return fmt.Errorf("array elements are different: %w", err)
   287  		}
   288  
   289  		if value1 == nil || value2 == nil {
   290  			break
   291  		}
   292  	}
   293  
   294  	return nil
   295  }
   296  
   297  func mapEqual(a atree.Value, b atree.Value) error {
   298  	m1, ok := a.(*atree.OrderedMap)
   299  	if !ok {
   300  		return fmt.Errorf("value %s type is %T, want *atree.OrderedMap", a, a)
   301  	}
   302  
   303  	m2, ok := b.(*atree.OrderedMap)
   304  	if !ok {
   305  		return fmt.Errorf("value %s type is %T, want *atree.OrderedMap", b, b)
   306  	}
   307  
   308  	if m1.Count() != m2.Count() {
   309  		return fmt.Errorf("map %s count %d != map %s count %d", m1, m1.Count(), m2, m2.Count())
   310  	}
   311  
   312  	iterator1, err := m1.Iterator()
   313  	if err != nil {
   314  		return fmt.Errorf("failed to get m1 iterator: %w", err)
   315  	}
   316  
   317  	iterator2, err := m2.Iterator()
   318  	if err != nil {
   319  		return fmt.Errorf("failed to get m2 iterator: %w", err)
   320  	}
   321  
   322  	for {
   323  		key1, value1, err := iterator1.Next()
   324  		if err != nil {
   325  			return fmt.Errorf("iterator1.Next() error: %w", err)
   326  		}
   327  
   328  		key2, value2, err := iterator2.Next()
   329  		if err != nil {
   330  			return fmt.Errorf("iterator2.Next() error: %w", err)
   331  		}
   332  
   333  		err = valueEqual(key1, key2)
   334  		if err != nil {
   335  			return fmt.Errorf("map keys are different: %w", err)
   336  		}
   337  
   338  		err = valueEqual(value1, value2)
   339  		if err != nil {
   340  			return fmt.Errorf("map values are different: %w", err)
   341  		}
   342  
   343  		if key1 == nil || key2 == nil {
   344  			break
   345  		}
   346  	}
   347  
   348  	return nil
   349  }
   350  
   351  // newArray creates atree.Array with random elements of specified size and nested level
   352  func newArray(storage *atree.PersistentSlabStorage, address atree.Address, length int, nestedLevel int) (*atree.Array, error) {
   353  	typeInfo := testTypeInfo{value: 123}
   354  
   355  	array, err := atree.NewArray(storage, address, typeInfo)
   356  	if err != nil {
   357  		return nil, fmt.Errorf("failed to create new array: %w", err)
   358  	}
   359  
   360  	values := make([]atree.Value, length)
   361  
   362  	for i := 0; i < length; i++ {
   363  		value, err := randomValue(storage, address, nestedLevel-1)
   364  		if err != nil {
   365  			return nil, err
   366  		}
   367  		copedValue, err := copyValue(storage, atree.Address{}, value)
   368  		if err != nil {
   369  			return nil, err
   370  		}
   371  		values[i] = copedValue
   372  		err = array.Append(value)
   373  		if err != nil {
   374  			return nil, err
   375  		}
   376  	}
   377  
   378  	err = checkArrayDataLoss(array, values)
   379  	if err != nil {
   380  		return nil, err
   381  	}
   382  
   383  	for _, v := range values {
   384  		err := removeValue(storage, v)
   385  		if err != nil {
   386  			return nil, err
   387  		}
   388  	}
   389  
   390  	return array, nil
   391  }
   392  
   393  // newMap creates atree.OrderedMap with random elements of specified size and nested level
   394  func newMap(storage *atree.PersistentSlabStorage, address atree.Address, length int, nestedLevel int) (*atree.OrderedMap, error) {
   395  	typeInfo := testTypeInfo{value: 123}
   396  
   397  	m, err := atree.NewMap(storage, address, atree.NewDefaultDigesterBuilder(), typeInfo)
   398  	if err != nil {
   399  		return nil, fmt.Errorf("failed to create new map: %w", err)
   400  	}
   401  
   402  	elements := make(map[atree.Value]atree.Value, length)
   403  
   404  	for i := 0; i < length; i++ {
   405  		k, err := randomKey()
   406  		if err != nil {
   407  			return nil, err
   408  		}
   409  
   410  		copiedKey, err := copyValue(storage, atree.Address{}, k)
   411  		if err != nil {
   412  			return nil, err
   413  		}
   414  
   415  		v, err := randomValue(storage, address, nestedLevel-1)
   416  		if err != nil {
   417  			return nil, err
   418  		}
   419  
   420  		copiedValue, err := copyValue(storage, atree.Address{}, v)
   421  		if err != nil {
   422  			return nil, err
   423  		}
   424  
   425  		elements[copiedKey] = copiedValue
   426  
   427  		existingStorable, err := m.Set(compare, hashInputProvider, k, v)
   428  		if err != nil {
   429  			return nil, err
   430  		}
   431  
   432  		if existingStorable != nil {
   433  			// Delete overwritten element
   434  			err = removeStorable(storage, existingStorable)
   435  			if err != nil {
   436  				return nil, fmt.Errorf("failed to remove storable element %s: %w", existingStorable, err)
   437  			}
   438  		}
   439  	}
   440  
   441  	err = checkMapDataLoss(m, elements)
   442  	if err != nil {
   443  		return nil, err
   444  	}
   445  
   446  	for k, v := range elements {
   447  		err := removeValue(storage, k)
   448  		if err != nil {
   449  			return nil, err
   450  		}
   451  		err = removeValue(storage, v)
   452  		if err != nil {
   453  			return nil, err
   454  		}
   455  	}
   456  
   457  	return m, nil
   458  }
   459  
   460  type InMemBaseStorage struct {
   461  	segments       map[atree.StorageID][]byte
   462  	storageIndex   map[atree.Address]atree.StorageIndex
   463  	bytesRetrieved int
   464  	bytesStored    int
   465  }
   466  
   467  var _ atree.BaseStorage = &InMemBaseStorage{}
   468  
   469  func NewInMemBaseStorage() *InMemBaseStorage {
   470  	return NewInMemBaseStorageFromMap(
   471  		make(map[atree.StorageID][]byte),
   472  	)
   473  }
   474  
   475  func NewInMemBaseStorageFromMap(segments map[atree.StorageID][]byte) *InMemBaseStorage {
   476  	return &InMemBaseStorage{
   477  		segments:     segments,
   478  		storageIndex: make(map[atree.Address]atree.StorageIndex),
   479  	}
   480  }
   481  
   482  func (s *InMemBaseStorage) Retrieve(id atree.StorageID) ([]byte, bool, error) {
   483  	seg, ok := s.segments[id]
   484  	s.bytesRetrieved += len(seg)
   485  	return seg, ok, nil
   486  }
   487  
   488  func (s *InMemBaseStorage) Store(id atree.StorageID, data []byte) error {
   489  	s.segments[id] = data
   490  	s.bytesStored += len(data)
   491  	return nil
   492  }
   493  
   494  func (s *InMemBaseStorage) Remove(id atree.StorageID) error {
   495  	delete(s.segments, id)
   496  	return nil
   497  }
   498  
   499  func (s *InMemBaseStorage) GenerateStorageID(address atree.Address) (atree.StorageID, error) {
   500  	index := s.storageIndex[address]
   501  	nextIndex := index.Next()
   502  
   503  	s.storageIndex[address] = nextIndex
   504  	return atree.NewStorageID(address, nextIndex), nil
   505  }
   506  
   507  func (s *InMemBaseStorage) SegmentCounts() int {
   508  	return len(s.segments)
   509  }
   510  
   511  func (s *InMemBaseStorage) Size() int {
   512  	total := 0
   513  	for _, seg := range s.segments {
   514  		total += len(seg)
   515  	}
   516  	return total
   517  }
   518  
   519  func (s *InMemBaseStorage) BytesRetrieved() int {
   520  	return s.bytesRetrieved
   521  }
   522  
   523  func (s *InMemBaseStorage) BytesStored() int {
   524  	return s.bytesStored
   525  }
   526  
   527  func (s *InMemBaseStorage) SegmentsReturned() int {
   528  	// not needed
   529  	return 0
   530  }
   531  
   532  func (s *InMemBaseStorage) SegmentsUpdated() int {
   533  	// not needed
   534  	return 0
   535  }
   536  
   537  func (s *InMemBaseStorage) SegmentsTouched() int {
   538  	// not needed
   539  	return 0
   540  }
   541  
   542  func (s *InMemBaseStorage) ResetReporter() {
   543  	// not needed
   544  }