github.com/wangyougui/gf/v2@v2.6.5/container/garray/garray_sorted_int.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/wangyougui/gf. 6 7 package garray 8 9 import ( 10 "bytes" 11 "fmt" 12 "math" 13 "sort" 14 15 "github.com/wangyougui/gf/v2/internal/json" 16 "github.com/wangyougui/gf/v2/internal/rwmutex" 17 "github.com/wangyougui/gf/v2/util/gconv" 18 "github.com/wangyougui/gf/v2/util/grand" 19 ) 20 21 // SortedIntArray is a golang sorted int array with rich features. 22 // It is using increasing order in default, which can be changed by 23 // setting it a custom comparator. 24 // It contains a concurrent-safe/unsafe switch, which should be set 25 // when its initialization and cannot be changed then. 26 type SortedIntArray struct { 27 mu rwmutex.RWMutex 28 array []int 29 unique bool // Whether enable unique feature(false) 30 comparator func(a, b int) int // Comparison function(it returns -1: a < b; 0: a == b; 1: a > b) 31 } 32 33 // NewSortedIntArray creates and returns an empty sorted array. 34 // The parameter `safe` is used to specify whether using array in concurrent-safety, 35 // which is false in default. 36 func NewSortedIntArray(safe ...bool) *SortedIntArray { 37 return NewSortedIntArraySize(0, safe...) 38 } 39 40 // NewSortedIntArrayComparator creates and returns an empty sorted array with specified comparator. 41 // The parameter `safe` is used to specify whether using array in concurrent-safety which is false in default. 42 func NewSortedIntArrayComparator(comparator func(a, b int) int, safe ...bool) *SortedIntArray { 43 array := NewSortedIntArray(safe...) 44 array.comparator = comparator 45 return array 46 } 47 48 // NewSortedIntArraySize create and returns an sorted array with given size and cap. 49 // The parameter `safe` is used to specify whether using array in concurrent-safety, 50 // which is false in default. 51 func NewSortedIntArraySize(cap int, safe ...bool) *SortedIntArray { 52 return &SortedIntArray{ 53 mu: rwmutex.Create(safe...), 54 array: make([]int, 0, cap), 55 comparator: defaultComparatorInt, 56 } 57 } 58 59 // NewSortedIntArrayRange creates and returns an array by a range from `start` to `end` 60 // with step value `step`. 61 func NewSortedIntArrayRange(start, end, step int, safe ...bool) *SortedIntArray { 62 if step == 0 { 63 panic(fmt.Sprintf(`invalid step value: %d`, step)) 64 } 65 slice := make([]int, 0) 66 index := 0 67 for i := start; i <= end; i += step { 68 slice = append(slice, i) 69 index++ 70 } 71 return NewSortedIntArrayFrom(slice, safe...) 72 } 73 74 // NewSortedIntArrayFrom creates and returns an sorted array with given slice `array`. 75 // The parameter `safe` is used to specify whether using array in concurrent-safety, 76 // which is false in default. 77 func NewSortedIntArrayFrom(array []int, safe ...bool) *SortedIntArray { 78 a := NewSortedIntArraySize(0, safe...) 79 a.array = array 80 sort.Ints(a.array) 81 return a 82 } 83 84 // NewSortedIntArrayFromCopy creates and returns an sorted array from a copy of given slice `array`. 85 // The parameter `safe` is used to specify whether using array in concurrent-safety, 86 // which is false in default. 87 func NewSortedIntArrayFromCopy(array []int, safe ...bool) *SortedIntArray { 88 newArray := make([]int, len(array)) 89 copy(newArray, array) 90 return NewSortedIntArrayFrom(newArray, safe...) 91 } 92 93 // At returns the value by the specified index. 94 // If the given `index` is out of range of the array, it returns `0`. 95 func (a *SortedIntArray) At(index int) (value int) { 96 value, _ = a.Get(index) 97 return 98 } 99 100 // SetArray sets the underlying slice array with the given `array`. 101 func (a *SortedIntArray) SetArray(array []int) *SortedIntArray { 102 a.mu.Lock() 103 defer a.mu.Unlock() 104 a.array = array 105 quickSortInt(a.array, a.getComparator()) 106 return a 107 } 108 109 // Sort sorts the array in increasing order. 110 // The parameter `reverse` controls whether sort 111 // in increasing order(default) or decreasing order. 112 func (a *SortedIntArray) Sort() *SortedIntArray { 113 a.mu.Lock() 114 defer a.mu.Unlock() 115 quickSortInt(a.array, a.getComparator()) 116 return a 117 } 118 119 // Add adds one or multiple values to sorted array, the array always keeps sorted. 120 // It's alias of function Append, see Append. 121 func (a *SortedIntArray) Add(values ...int) *SortedIntArray { 122 return a.Append(values...) 123 } 124 125 // Append adds one or multiple values to sorted array, the array always keeps sorted. 126 func (a *SortedIntArray) Append(values ...int) *SortedIntArray { 127 if len(values) == 0 { 128 return a 129 } 130 a.mu.Lock() 131 defer a.mu.Unlock() 132 for _, value := range values { 133 index, cmp := a.binSearch(value, false) 134 if a.unique && cmp == 0 { 135 continue 136 } 137 if index < 0 { 138 a.array = append(a.array, value) 139 continue 140 } 141 if cmp > 0 { 142 index++ 143 } 144 rear := append([]int{}, a.array[index:]...) 145 a.array = append(a.array[0:index], value) 146 a.array = append(a.array, rear...) 147 } 148 return a 149 } 150 151 // Get returns the value by the specified index. 152 // If the given `index` is out of range of the array, the `found` is false. 153 func (a *SortedIntArray) Get(index int) (value int, found bool) { 154 a.mu.RLock() 155 defer a.mu.RUnlock() 156 if index < 0 || index >= len(a.array) { 157 return 0, false 158 } 159 return a.array[index], true 160 } 161 162 // Remove removes an item by index. 163 // If the given `index` is out of range of the array, the `found` is false. 164 func (a *SortedIntArray) Remove(index int) (value int, found bool) { 165 a.mu.Lock() 166 defer a.mu.Unlock() 167 return a.doRemoveWithoutLock(index) 168 } 169 170 // doRemoveWithoutLock removes an item by index without lock. 171 func (a *SortedIntArray) doRemoveWithoutLock(index int) (value int, found bool) { 172 if index < 0 || index >= len(a.array) { 173 return 0, false 174 } 175 // Determine array boundaries when deleting to improve deletion efficiency. 176 if index == 0 { 177 value := a.array[0] 178 a.array = a.array[1:] 179 return value, true 180 } else if index == len(a.array)-1 { 181 value := a.array[index] 182 a.array = a.array[:index] 183 return value, true 184 } 185 // If it is a non-boundary delete, 186 // it will involve the creation of an array, 187 // then the deletion is less efficient. 188 value = a.array[index] 189 a.array = append(a.array[:index], a.array[index+1:]...) 190 return value, true 191 } 192 193 // RemoveValue removes an item by value. 194 // It returns true if value is found in the array, or else false if not found. 195 func (a *SortedIntArray) RemoveValue(value int) bool { 196 a.mu.Lock() 197 defer a.mu.Unlock() 198 if i, r := a.binSearch(value, false); r == 0 { 199 _, res := a.doRemoveWithoutLock(i) 200 return res 201 } 202 return false 203 } 204 205 // RemoveValues removes an item by `values`. 206 func (a *SortedIntArray) RemoveValues(values ...int) { 207 a.mu.Lock() 208 defer a.mu.Unlock() 209 for _, value := range values { 210 if i, r := a.binSearch(value, false); r == 0 { 211 a.doRemoveWithoutLock(i) 212 } 213 } 214 } 215 216 // PopLeft pops and returns an item from the beginning of array. 217 // Note that if the array is empty, the `found` is false. 218 func (a *SortedIntArray) PopLeft() (value int, found bool) { 219 a.mu.Lock() 220 defer a.mu.Unlock() 221 if len(a.array) == 0 { 222 return 0, false 223 } 224 value = a.array[0] 225 a.array = a.array[1:] 226 return value, true 227 } 228 229 // PopRight pops and returns an item from the end of array. 230 // Note that if the array is empty, the `found` is false. 231 func (a *SortedIntArray) PopRight() (value int, found bool) { 232 a.mu.Lock() 233 defer a.mu.Unlock() 234 index := len(a.array) - 1 235 if index < 0 { 236 return 0, false 237 } 238 value = a.array[index] 239 a.array = a.array[:index] 240 return value, true 241 } 242 243 // PopRand randomly pops and return an item out of array. 244 // Note that if the array is empty, the `found` is false. 245 func (a *SortedIntArray) PopRand() (value int, found bool) { 246 a.mu.Lock() 247 defer a.mu.Unlock() 248 return a.doRemoveWithoutLock(grand.Intn(len(a.array))) 249 } 250 251 // PopRands randomly pops and returns `size` items out of array. 252 // If the given `size` is greater than size of the array, it returns all elements of the array. 253 // Note that if given `size` <= 0 or the array is empty, it returns nil. 254 func (a *SortedIntArray) PopRands(size int) []int { 255 a.mu.Lock() 256 defer a.mu.Unlock() 257 if size <= 0 || len(a.array) == 0 { 258 return nil 259 } 260 if size >= len(a.array) { 261 size = len(a.array) 262 } 263 array := make([]int, size) 264 for i := 0; i < size; i++ { 265 array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) 266 } 267 return array 268 } 269 270 // PopLefts pops and returns `size` items from the beginning of array. 271 // If the given `size` is greater than size of the array, it returns all elements of the array. 272 // Note that if given `size` <= 0 or the array is empty, it returns nil. 273 func (a *SortedIntArray) PopLefts(size int) []int { 274 a.mu.Lock() 275 defer a.mu.Unlock() 276 if size <= 0 || len(a.array) == 0 { 277 return nil 278 } 279 if size >= len(a.array) { 280 array := a.array 281 a.array = a.array[:0] 282 return array 283 } 284 value := a.array[0:size] 285 a.array = a.array[size:] 286 return value 287 } 288 289 // PopRights pops and returns `size` items from the end of array. 290 // If the given `size` is greater than size of the array, it returns all elements of the array. 291 // Note that if given `size` <= 0 or the array is empty, it returns nil. 292 func (a *SortedIntArray) PopRights(size int) []int { 293 a.mu.Lock() 294 defer a.mu.Unlock() 295 if size <= 0 || len(a.array) == 0 { 296 return nil 297 } 298 index := len(a.array) - size 299 if index <= 0 { 300 array := a.array 301 a.array = a.array[:0] 302 return array 303 } 304 value := a.array[index:] 305 a.array = a.array[:index] 306 return value 307 } 308 309 // Range picks and returns items by range, like array[start:end]. 310 // Notice, if in concurrent-safe usage, it returns a copy of slice; 311 // else a pointer to the underlying data. 312 // 313 // If `end` is negative, then the offset will start from the end of array. 314 // If `end` is omitted, then the sequence will have everything from start up 315 // until the end of the array. 316 func (a *SortedIntArray) Range(start int, end ...int) []int { 317 a.mu.RLock() 318 defer a.mu.RUnlock() 319 offsetEnd := len(a.array) 320 if len(end) > 0 && end[0] < offsetEnd { 321 offsetEnd = end[0] 322 } 323 if start > offsetEnd { 324 return nil 325 } 326 if start < 0 { 327 start = 0 328 } 329 array := ([]int)(nil) 330 if a.mu.IsSafe() { 331 array = make([]int, offsetEnd-start) 332 copy(array, a.array[start:offsetEnd]) 333 } else { 334 array = a.array[start:offsetEnd] 335 } 336 return array 337 } 338 339 // SubSlice returns a slice of elements from the array as specified 340 // by the `offset` and `size` parameters. 341 // If in concurrent safe usage, it returns a copy of the slice; else a pointer. 342 // 343 // If offset is non-negative, the sequence will start at that offset in the array. 344 // If offset is negative, the sequence will start that far from the end of the array. 345 // 346 // If length is given and is positive, then the sequence will have up to that many elements in it. 347 // If the array is shorter than the length, then only the available array elements will be present. 348 // If length is given and is negative then the sequence will stop that many elements from the end of the array. 349 // If it is omitted, then the sequence will have everything from offset up until the end of the array. 350 // 351 // Any possibility crossing the left border of array, it will fail. 352 func (a *SortedIntArray) SubSlice(offset int, length ...int) []int { 353 a.mu.RLock() 354 defer a.mu.RUnlock() 355 size := len(a.array) 356 if len(length) > 0 { 357 size = length[0] 358 } 359 if offset > len(a.array) { 360 return nil 361 } 362 if offset < 0 { 363 offset = len(a.array) + offset 364 if offset < 0 { 365 return nil 366 } 367 } 368 if size < 0 { 369 offset += size 370 size = -size 371 if offset < 0 { 372 return nil 373 } 374 } 375 end := offset + size 376 if end > len(a.array) { 377 end = len(a.array) 378 size = len(a.array) - offset 379 } 380 if a.mu.IsSafe() { 381 s := make([]int, size) 382 copy(s, a.array[offset:]) 383 return s 384 } else { 385 return a.array[offset:end] 386 } 387 } 388 389 // Len returns the length of array. 390 func (a *SortedIntArray) Len() int { 391 a.mu.RLock() 392 length := len(a.array) 393 a.mu.RUnlock() 394 return length 395 } 396 397 // Sum returns the sum of values in an array. 398 func (a *SortedIntArray) Sum() (sum int) { 399 a.mu.RLock() 400 defer a.mu.RUnlock() 401 for _, v := range a.array { 402 sum += v 403 } 404 return 405 } 406 407 // Slice returns the underlying data of array. 408 // Note that, if it's in concurrent-safe usage, it returns a copy of underlying data, 409 // or else a pointer to the underlying data. 410 func (a *SortedIntArray) Slice() []int { 411 array := ([]int)(nil) 412 if a.mu.IsSafe() { 413 a.mu.RLock() 414 defer a.mu.RUnlock() 415 array = make([]int, len(a.array)) 416 copy(array, a.array) 417 } else { 418 array = a.array 419 } 420 return array 421 } 422 423 // Interfaces returns current array as []interface{}. 424 func (a *SortedIntArray) Interfaces() []interface{} { 425 a.mu.RLock() 426 defer a.mu.RUnlock() 427 array := make([]interface{}, len(a.array)) 428 for k, v := range a.array { 429 array[k] = v 430 } 431 return array 432 } 433 434 // Contains checks whether a value exists in the array. 435 func (a *SortedIntArray) Contains(value int) bool { 436 return a.Search(value) != -1 437 } 438 439 // Search searches array by `value`, returns the index of `value`, 440 // or returns -1 if not exists. 441 func (a *SortedIntArray) Search(value int) (index int) { 442 if i, r := a.binSearch(value, true); r == 0 { 443 return i 444 } 445 return -1 446 } 447 448 // Binary search. 449 // It returns the last compared index and the result. 450 // If `result` equals to 0, it means the value at `index` is equals to `value`. 451 // If `result` lesser than 0, it means the value at `index` is lesser than `value`. 452 // If `result` greater than 0, it means the value at `index` is greater than `value`. 453 func (a *SortedIntArray) binSearch(value int, lock bool) (index int, result int) { 454 if lock { 455 a.mu.RLock() 456 defer a.mu.RUnlock() 457 } 458 if len(a.array) == 0 { 459 return -1, -2 460 } 461 min := 0 462 max := len(a.array) - 1 463 mid := 0 464 cmp := -2 465 for min <= max { 466 mid = min + int((max-min)/2) 467 cmp = a.getComparator()(value, a.array[mid]) 468 switch { 469 case cmp < 0: 470 max = mid - 1 471 case cmp > 0: 472 min = mid + 1 473 default: 474 return mid, cmp 475 } 476 } 477 return mid, cmp 478 } 479 480 // SetUnique sets unique mark to the array, 481 // which means it does not contain any repeated items. 482 // It also do unique check, remove all repeated items. 483 func (a *SortedIntArray) SetUnique(unique bool) *SortedIntArray { 484 oldUnique := a.unique 485 a.unique = unique 486 if unique && oldUnique != unique { 487 a.Unique() 488 } 489 return a 490 } 491 492 // Unique uniques the array, clear repeated items. 493 func (a *SortedIntArray) Unique() *SortedIntArray { 494 a.mu.Lock() 495 defer a.mu.Unlock() 496 if len(a.array) == 0 { 497 return a 498 } 499 i := 0 500 for { 501 if i == len(a.array)-1 { 502 break 503 } 504 if a.getComparator()(a.array[i], a.array[i+1]) == 0 { 505 a.array = append(a.array[:i+1], a.array[i+1+1:]...) 506 } else { 507 i++ 508 } 509 } 510 return a 511 } 512 513 // Clone returns a new array, which is a copy of current array. 514 func (a *SortedIntArray) Clone() (newArray *SortedIntArray) { 515 a.mu.RLock() 516 array := make([]int, len(a.array)) 517 copy(array, a.array) 518 a.mu.RUnlock() 519 return NewSortedIntArrayFrom(array, a.mu.IsSafe()) 520 } 521 522 // Clear deletes all items of current array. 523 func (a *SortedIntArray) Clear() *SortedIntArray { 524 a.mu.Lock() 525 if len(a.array) > 0 { 526 a.array = make([]int, 0) 527 } 528 a.mu.Unlock() 529 return a 530 } 531 532 // LockFunc locks writing by callback function `f`. 533 func (a *SortedIntArray) LockFunc(f func(array []int)) *SortedIntArray { 534 a.mu.Lock() 535 defer a.mu.Unlock() 536 f(a.array) 537 return a 538 } 539 540 // RLockFunc locks reading by callback function `f`. 541 func (a *SortedIntArray) RLockFunc(f func(array []int)) *SortedIntArray { 542 a.mu.RLock() 543 defer a.mu.RUnlock() 544 f(a.array) 545 return a 546 } 547 548 // Merge merges `array` into current array. 549 // The parameter `array` can be any garray or slice type. 550 // The difference between Merge and Append is Append supports only specified slice type, 551 // but Merge supports more parameter types. 552 func (a *SortedIntArray) Merge(array interface{}) *SortedIntArray { 553 return a.Add(gconv.Ints(array)...) 554 } 555 556 // Chunk splits an array into multiple arrays, 557 // the size of each array is determined by `size`. 558 // The last chunk may contain less than size elements. 559 func (a *SortedIntArray) Chunk(size int) [][]int { 560 if size < 1 { 561 return nil 562 } 563 a.mu.RLock() 564 defer a.mu.RUnlock() 565 length := len(a.array) 566 chunks := int(math.Ceil(float64(length) / float64(size))) 567 var n [][]int 568 for i, end := 0, 0; chunks > 0; chunks-- { 569 end = (i + 1) * size 570 if end > length { 571 end = length 572 } 573 n = append(n, a.array[i*size:end]) 574 i++ 575 } 576 return n 577 } 578 579 // Rand randomly returns one item from array(no deleting). 580 func (a *SortedIntArray) Rand() (value int, found bool) { 581 a.mu.RLock() 582 defer a.mu.RUnlock() 583 if len(a.array) == 0 { 584 return 0, false 585 } 586 return a.array[grand.Intn(len(a.array))], true 587 } 588 589 // Rands randomly returns `size` items from array(no deleting). 590 func (a *SortedIntArray) Rands(size int) []int { 591 a.mu.RLock() 592 defer a.mu.RUnlock() 593 if size <= 0 || len(a.array) == 0 { 594 return nil 595 } 596 array := make([]int, size) 597 for i := 0; i < size; i++ { 598 array[i] = a.array[grand.Intn(len(a.array))] 599 } 600 return array 601 } 602 603 // Join joins array elements with a string `glue`. 604 func (a *SortedIntArray) Join(glue string) string { 605 a.mu.RLock() 606 defer a.mu.RUnlock() 607 if len(a.array) == 0 { 608 return "" 609 } 610 buffer := bytes.NewBuffer(nil) 611 for k, v := range a.array { 612 buffer.WriteString(gconv.String(v)) 613 if k != len(a.array)-1 { 614 buffer.WriteString(glue) 615 } 616 } 617 return buffer.String() 618 } 619 620 // CountValues counts the number of occurrences of all values in the array. 621 func (a *SortedIntArray) CountValues() map[int]int { 622 m := make(map[int]int) 623 a.mu.RLock() 624 defer a.mu.RUnlock() 625 for _, v := range a.array { 626 m[v]++ 627 } 628 return m 629 } 630 631 // Iterator is alias of IteratorAsc. 632 func (a *SortedIntArray) Iterator(f func(k int, v int) bool) { 633 a.IteratorAsc(f) 634 } 635 636 // IteratorAsc iterates the array readonly in ascending order with given callback function `f`. 637 // If `f` returns true, then it continues iterating; or false to stop. 638 func (a *SortedIntArray) IteratorAsc(f func(k int, v int) bool) { 639 a.mu.RLock() 640 defer a.mu.RUnlock() 641 for k, v := range a.array { 642 if !f(k, v) { 643 break 644 } 645 } 646 } 647 648 // IteratorDesc iterates the array readonly in descending order with given callback function `f`. 649 // If `f` returns true, then it continues iterating; or false to stop. 650 func (a *SortedIntArray) IteratorDesc(f func(k int, v int) bool) { 651 a.mu.RLock() 652 defer a.mu.RUnlock() 653 for i := len(a.array) - 1; i >= 0; i-- { 654 if !f(i, a.array[i]) { 655 break 656 } 657 } 658 } 659 660 // String returns current array as a string, which implements like json.Marshal does. 661 func (a *SortedIntArray) String() string { 662 if a == nil { 663 return "" 664 } 665 return "[" + a.Join(",") + "]" 666 } 667 668 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 669 // Note that do not use pointer as its receiver here. 670 func (a SortedIntArray) MarshalJSON() ([]byte, error) { 671 a.mu.RLock() 672 defer a.mu.RUnlock() 673 return json.Marshal(a.array) 674 } 675 676 // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. 677 func (a *SortedIntArray) UnmarshalJSON(b []byte) error { 678 if a.comparator == nil { 679 a.array = make([]int, 0) 680 a.comparator = defaultComparatorInt 681 } 682 a.mu.Lock() 683 defer a.mu.Unlock() 684 if err := json.UnmarshalUseNumber(b, &a.array); err != nil { 685 return err 686 } 687 if a.array != nil { 688 sort.Ints(a.array) 689 } 690 return nil 691 } 692 693 // UnmarshalValue is an interface implement which sets any type of value for array. 694 func (a *SortedIntArray) UnmarshalValue(value interface{}) (err error) { 695 if a.comparator == nil { 696 a.comparator = defaultComparatorInt 697 } 698 a.mu.Lock() 699 defer a.mu.Unlock() 700 switch value.(type) { 701 case string, []byte: 702 err = json.UnmarshalUseNumber(gconv.Bytes(value), &a.array) 703 default: 704 a.array = gconv.SliceInt(value) 705 } 706 if a.array != nil { 707 sort.Ints(a.array) 708 } 709 return err 710 } 711 712 // Filter iterates array and filters elements using custom callback function. 713 // It removes the element from array if callback function `filter` returns true, 714 // it or else does nothing and continues iterating. 715 func (a *SortedIntArray) Filter(filter func(index int, value int) bool) *SortedIntArray { 716 a.mu.Lock() 717 defer a.mu.Unlock() 718 for i := 0; i < len(a.array); { 719 if filter(i, a.array[i]) { 720 a.array = append(a.array[:i], a.array[i+1:]...) 721 } else { 722 i++ 723 } 724 } 725 return a 726 } 727 728 // FilterEmpty removes all zero value of the array. 729 func (a *SortedIntArray) FilterEmpty() *SortedIntArray { 730 a.mu.Lock() 731 defer a.mu.Unlock() 732 for i := 0; i < len(a.array); { 733 if a.array[i] == 0 { 734 a.array = append(a.array[:i], a.array[i+1:]...) 735 } else { 736 break 737 } 738 } 739 for i := len(a.array) - 1; i >= 0; { 740 if a.array[i] == 0 { 741 a.array = append(a.array[:i], a.array[i+1:]...) 742 } else { 743 break 744 } 745 } 746 return a 747 } 748 749 // Walk applies a user supplied function `f` to every item of array. 750 func (a *SortedIntArray) Walk(f func(value int) int) *SortedIntArray { 751 a.mu.Lock() 752 defer a.mu.Unlock() 753 754 // Keep the array always sorted. 755 defer quickSortInt(a.array, a.getComparator()) 756 757 for i, v := range a.array { 758 a.array[i] = f(v) 759 } 760 return a 761 } 762 763 // IsEmpty checks whether the array is empty. 764 func (a *SortedIntArray) IsEmpty() bool { 765 return a.Len() == 0 766 } 767 768 // getComparator returns the comparator if it's previously set, 769 // or else it returns a default comparator. 770 func (a *SortedIntArray) getComparator() func(a, b int) int { 771 if a.comparator == nil { 772 return defaultComparatorInt 773 } 774 return a.comparator 775 } 776 777 // DeepCopy implements interface for deep copy of current type. 778 func (a *SortedIntArray) DeepCopy() interface{} { 779 if a == nil { 780 return nil 781 } 782 a.mu.RLock() 783 defer a.mu.RUnlock() 784 newSlice := make([]int, len(a.array)) 785 copy(newSlice, a.array) 786 return NewSortedIntArrayFrom(newSlice, a.mu.IsSafe()) 787 }