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 }