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

     1  package util
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  )
     7  
     8  // util.RamUsageEstimator.java
     9  
    10  // amd64 system
    11  const (
    12  	NUM_BYTES_CHAR  = 2 // UTF8 uses 1-4 bytes to represent each rune
    13  	NUM_BYTES_SHORT = 2
    14  	NUM_BYTES_INT   = 8
    15  	NUM_BYTES_FLOAT = 4
    16  	NUM_BYTES_LONG  = 8
    17  
    18  	/* Number of bytes to represent an object reference */
    19  	NUM_BYTES_OBJECT_REF = 8
    20  
    21  	// Number of bytes to represent an object header (no fields, no alignments).
    22  	NUM_BYTES_OBJECT_HEADER = 16
    23  
    24  	// Number of bytes to represent an array header (no content, but with alignments).
    25  	NUM_BYTES_ARRAY_HEADER = 24
    26  
    27  	// A constant specifying the object alignment boundary inside the
    28  	// JVM. Objects will always take a full multiple of this constant,
    29  	// possibly wasting some space.
    30  	NUM_BYTES_OBJECT_ALIGNMENT = 8
    31  )
    32  
    33  /* Aligns an object size to be the next multiple of NUM_BYTES_OBJECT_ALIGNMENT */
    34  func AlignObjectSize(size int64) int64 {
    35  	size += NUM_BYTES_OBJECT_ALIGNMENT - 1
    36  	return size - (size & NUM_BYTES_OBJECT_ALIGNMENT)
    37  }
    38  
    39  /* Returns the size in bytes of the object. */
    40  func SizeOf(arr interface{}) int64 {
    41  	if arr == nil {
    42  		return 0
    43  	}
    44  	switch arr.(type) {
    45  	case []int64:
    46  		return AlignObjectSize(NUM_BYTES_ARRAY_HEADER + NUM_BYTES_LONG*int64(len(arr.([]int64))))
    47  	case []int16:
    48  		return AlignObjectSize(NUM_BYTES_ARRAY_HEADER + NUM_BYTES_SHORT*int64(len(arr.([]int16))))
    49  	case []byte:
    50  		return AlignObjectSize(NUM_BYTES_ARRAY_HEADER + int64(len(arr.([]byte))))
    51  	default:
    52  		if t := reflect.TypeOf(arr); t.Kind() == reflect.Slice {
    53  			var size int64
    54  			v := reflect.ValueOf(arr)
    55  			for i := 0; i < v.Len(); i++ {
    56  				size += v.Index(i).Interface().(Accountable).RamBytesUsed()
    57  			}
    58  			return size
    59  		}
    60  		fmt.Println("Unknown type:", reflect.TypeOf(arr))
    61  		panic("not supported yet")
    62  	}
    63  }
    64  
    65  /*
    66  Estimates a "shallow" memory usage of the given object. For slices,
    67  this will be the memory taken by slice storage (no subreferences will
    68  be followed). For objects, this will be the memory taken by the fields.
    69  */
    70  func ShallowSizeOf(obj interface{}) int64 {
    71  	if obj == nil {
    72  		return 0
    73  	}
    74  	clz := reflect.TypeOf(obj)
    75  	if clz.Kind() == reflect.Slice {
    76  		return shallowSizeOfArray(obj)
    77  	}
    78  	return ShallowSizeOfInstance(clz)
    79  }
    80  
    81  func ShallowSizeOfInstance(clazz reflect.Type) int64 {
    82  	// TODO later
    83  	fmt.Printf("[TODO] ShallowSizeOfInstance(%v)\n", clazz)
    84  	return 0
    85  }
    86  
    87  /* Return shallow size of any array */
    88  func shallowSizeOfArray(arr interface{}) int64 {
    89  	size := int64(NUM_BYTES_ARRAY_HEADER)
    90  	v := reflect.ValueOf(arr)
    91  	if length := v.Len(); length > 0 {
    92  		switch v.Kind() {
    93  		case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16,
    94  			reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8,
    95  			reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32,
    96  			reflect.Float64, reflect.Complex64, reflect.Complex128:
    97  			// primitive type
    98  			size += int64(length) * int64(v.Elem().Type().Size())
    99  		default:
   100  			size += int64(length * NUM_BYTES_OBJECT_REF)
   101  		}
   102  	}
   103  	return AlignObjectSize(size)
   104  }