github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/array.go (about)

     1  package util
     2  
     3  import (
     4  	"math"
     5  	"sort"
     6  )
     7  
     8  // util/ArrayUtil.java
     9  
    10  /* Maximum length for an array */
    11  const MAX_ARRAY_LENGTH = math.MaxInt32 - NUM_BYTES_ARRAY_HEADER
    12  
    13  // L152
    14  /** Returns an array size >= minTargetSize, generally
    15   *  over-allocating exponentially to achieve amortized
    16   *  linear-time cost as the array grows.
    17   *
    18   *  NOTE: this was originally borrowed from Python 2.4.2
    19   *  listobject.c sources (attribution in LICENSE.txt), but
    20   *  has now been substantially changed based on
    21   *  discussions from java-dev thread with subject "Dynamic
    22   *  array reallocation algorithms", started on Jan 12
    23   *  2010.
    24   *
    25   * @param minTargetSize Minimum required value to be returned.
    26   * @param bytesPerElement Bytes used by each element of
    27   * the array.  See constants in {@link RamUsageEstimator}.
    28   *
    29   * @lucene.internal
    30   */
    31  func Oversize(minTargetSize int, bytesPerElement int) int {
    32  	// catch usage that accidentally overflows int
    33  	assert2(minTargetSize >= 0, "invalid array size %v", minTargetSize)
    34  
    35  	if minTargetSize == 0 {
    36  		// wait until at least one element is requested
    37  		return 0
    38  	}
    39  
    40  	assert2(minTargetSize <= MAX_ARRAY_LENGTH,
    41  		"requested array size %v exceeds maximum array in Go (%v)", MAX_ARRAY_LENGTH)
    42  
    43  	// asymptotic exponential growth by 1/8th, favors
    44  	// spending a bit more CPU to not tie up too much wasted
    45  	// RAM:
    46  	extra := minTargetSize >> 3
    47  	if extra < 3 {
    48  		// for very small arrays, where constant overhead of
    49  		// realloc is presumably relatively high, we grow
    50  		// faster
    51  		extra = 3
    52  	}
    53  
    54  	newSize := minTargetSize + extra
    55  	// add 7 to allow for worst case byte alignment addition below:
    56  	if n := int32(newSize + 7); n < 0 || n > MAX_ARRAY_LENGTH {
    57  		// int overflowed, or we exceeded the maximum array length
    58  		return MAX_ARRAY_LENGTH
    59  	}
    60  
    61  	// Lucene support 32bit/64bit detection
    62  	// However I assume golucene in 64bit only
    63  	// if is64bit {
    64  	// round up to 8 byte alignment in 64bit env
    65  	switch bytesPerElement {
    66  	case 4:
    67  		// round up to multiple of 2
    68  		return (newSize + 1) & 0x7ffffffe
    69  	case 2:
    70  		// round up to multiple of 4
    71  		return (newSize + 3) & 0x7ffffffc
    72  	case 1:
    73  		// round up to multiple of 8
    74  		return (newSize + 7) & 0x7ffffff8
    75  	case 8:
    76  		// no rounding
    77  		return newSize
    78  	default:
    79  		// odd (invalid?) size
    80  		return newSize
    81  	}
    82  	// }
    83  }
    84  
    85  // L285
    86  func GrowIntSlice(arr []int, minSize int) []int {
    87  	assert2(minSize >= 0, "size must be positive (got %v): likely integer overflow?", minSize)
    88  	if len(arr) < minSize {
    89  		newArr := make([]int, Oversize(minSize, NUM_BYTES_INT))
    90  		copy(newArr, arr)
    91  		return newArr
    92  	}
    93  	return arr
    94  }
    95  
    96  // L343
    97  func GrowByteSlice(arr []byte, minSize int) []byte {
    98  	assert2(minSize >= 0, "size must be positive (got %v): likely integer overflow?", minSize)
    99  	if cap(arr) < minSize {
   100  		newArr := make([]byte, Oversize(minSize, 1))
   101  		copy(newArr, arr)
   102  		return newArr[:minSize]
   103  	}
   104  	for len(arr) < minSize {
   105  		arr = append(arr, 0)
   106  	}
   107  	return arr
   108  }
   109  
   110  // L699
   111  /*
   112  Sorts the given array slice in its own order. This method uses the
   113  Tim sort algorithm, but falls back to binary sort for small arrays.
   114  */
   115  func TimSort(data sort.Interface) {
   116  	newArrayTimSorter(data, data.Len()/64).sort(0, data.Len())
   117  }
   118  
   119  // util/ArrayTimSorter.java
   120  
   121  // A TimSorter for object arrays
   122  type ArrayTimSorter struct {
   123  	*TimSorter
   124  	arr sort.Interface
   125  	tmp []interface{}
   126  }
   127  
   128  // Create a new ArrayTimSorter
   129  func newArrayTimSorter(arr sort.Interface, maxTempSlots int) *ArrayTimSorter {
   130  	ans := &ArrayTimSorter{
   131  		TimSorter: newTimSorter(arr, maxTempSlots),
   132  		arr:       arr,
   133  	}
   134  	if maxTempSlots > 0 {
   135  		ans.tmp = make([]interface{}, maxTempSlots)
   136  	}
   137  	return ans
   138  }