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

     1  package packed
     2  
     3  // packed/AbstractPagedMutable.java
     4  
     5  const MIN_BLOCK_SIZE = 1 << 6
     6  const MAX_BLOCK_SIZE = 1 << 30
     7  
     8  type abstractPagedMutableSPI interface {
     9  	newMutable(int, int) Mutable
    10  }
    11  
    12  type abstractPagedMutable struct {
    13  	spi          abstractPagedMutableSPI
    14  	size         int64
    15  	pageShift    uint
    16  	pageMask     int
    17  	subMutables  []Mutable
    18  	bitsPerValue int
    19  }
    20  
    21  func newAbstractPagedMutable(spi abstractPagedMutableSPI,
    22  	bitsPerValue int, size int64, pageSize int) *abstractPagedMutable {
    23  	numPages := numBlocks(size, pageSize)
    24  	return &abstractPagedMutable{
    25  		spi:          spi,
    26  		bitsPerValue: bitsPerValue,
    27  		size:         size,
    28  		pageShift:    uint(checkBlockSize(pageSize, MIN_BLOCK_SIZE, MAX_BLOCK_SIZE)),
    29  		pageMask:     pageSize - 1,
    30  		subMutables:  make([]Mutable, numPages),
    31  	}
    32  }
    33  
    34  func (m *abstractPagedMutable) fillPages() {
    35  	numPages := numBlocks(m.size, m.pageSize())
    36  	for i := 0; i < numPages; i++ {
    37  		// do not allocate for more entries than necessary on the last page
    38  		var valueCount int
    39  		if i == numPages-1 {
    40  			valueCount = m.lastPageSize(m.size)
    41  		} else {
    42  			valueCount = m.pageSize()
    43  		}
    44  		m.subMutables[i] = m.spi.newMutable(valueCount, m.bitsPerValue)
    45  	}
    46  }
    47  
    48  func (m *abstractPagedMutable) lastPageSize(size int64) int {
    49  	if sz := m.indexInPage(size); sz != 0 {
    50  		return sz
    51  	}
    52  	return m.pageSize()
    53  }
    54  
    55  func (m *abstractPagedMutable) pageSize() int {
    56  	return m.pageMask + 1
    57  }
    58  
    59  func (m *abstractPagedMutable) Size() int64 {
    60  	return m.size
    61  }
    62  
    63  func (m *abstractPagedMutable) pageIndex(index int64) int {
    64  	return int(uint64(index) >> m.pageShift)
    65  }
    66  
    67  func (m *abstractPagedMutable) indexInPage(index int64) int {
    68  	return int(index & int64(m.pageMask))
    69  }
    70  
    71  func (m *abstractPagedMutable) Get(index int64) int64 {
    72  	assert(index >= 0 && index < m.size)
    73  	pageIndex := m.pageIndex(index)
    74  	indexInPage := m.indexInPage(index)
    75  	return m.subMutables[pageIndex].Get(indexInPage)
    76  }
    77  
    78  /* set value at index. */
    79  func (m *abstractPagedMutable) Set(index, value int64) {
    80  	assert(index >= 0 && index < m.size)
    81  	pageIndex := m.pageIndex(index)
    82  	indexInPage := m.indexInPage(index)
    83  	m.subMutables[pageIndex].Set(indexInPage, value)
    84  }
    85  
    86  // packed/PagedGrowableWriter.java
    87  
    88  /*
    89  A PagedGrowableWriter. This class slices data into fixed-size blocks
    90  which have independent numbers of bits per value and grow on-demand.
    91  
    92  You should use this class instead of the AbstractAppendingLongBuffer
    93  related ones only when you need random write-access. Otherwise this
    94  class will likely be slower and less memory-efficient.
    95  */
    96  type PagedGrowableWriter struct {
    97  	*abstractPagedMutable
    98  	acceptableOverheadRatio float32
    99  }
   100  
   101  /* Create a new PagedGrowableWriter instance. */
   102  func NewPagedGrowableWriter(size int64, pageSize, startBitsPerValue int,
   103  	acceptableOverheadRatio float32) *PagedGrowableWriter {
   104  	return newPagedGrowableWriter(size, pageSize, startBitsPerValue, acceptableOverheadRatio, true)
   105  }
   106  
   107  func newPagedGrowableWriter(size int64, pageSize, startBitsPerValue int,
   108  	acceptableOverheadRatio float32, fillPages bool) *PagedGrowableWriter {
   109  	ans := &PagedGrowableWriter{acceptableOverheadRatio: acceptableOverheadRatio}
   110  	ans.abstractPagedMutable = newAbstractPagedMutable(ans, startBitsPerValue, size, pageSize)
   111  	if fillPages {
   112  		ans.fillPages()
   113  	}
   114  	return ans
   115  }
   116  
   117  func (w *PagedGrowableWriter) newMutable(valueCount, bitsPerValue int) Mutable {
   118  	return NewGrowableWriter(bitsPerValue, valueCount, w.acceptableOverheadRatio)
   119  }