diff options
Diffstat (limited to 'src/main/java/org/elasticsearch/common/util/BigDoubleArray.java')
-rw-r--r-- | src/main/java/org/elasticsearch/common/util/BigDoubleArray.java | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/main/java/org/elasticsearch/common/util/BigDoubleArray.java b/src/main/java/org/elasticsearch/common/util/BigDoubleArray.java new file mode 100644 index 0000000..e39b38f --- /dev/null +++ b/src/main/java/org/elasticsearch/common/util/BigDoubleArray.java @@ -0,0 +1,110 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.common.util; + +import com.google.common.base.Preconditions; +import org.apache.lucene.util.ArrayUtil; +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.cache.recycler.PageCacheRecycler; + +import java.util.Arrays; + +import static org.elasticsearch.common.util.BigArrays.DOUBLE_PAGE_SIZE; + +/** + * Double array abstraction able to support more than 2B values. This implementation slices data into fixed-sized blocks of + * configurable length. + */ +final class BigDoubleArray extends AbstractBigArray implements DoubleArray { + + private double[][] pages; + + /** Constructor. */ + public BigDoubleArray(long size, PageCacheRecycler recycler, boolean clearOnResize) { + super(DOUBLE_PAGE_SIZE, recycler, clearOnResize); + this.size = size; + pages = new double[numPages(size)][]; + for (int i = 0; i < pages.length; ++i) { + pages[i] = newDoublePage(i); + } + } + + @Override + public double get(long index) { + final int pageIndex = pageIndex(index); + final int indexInPage = indexInPage(index); + return pages[pageIndex][indexInPage]; + } + + @Override + public double set(long index, double value) { + final int pageIndex = pageIndex(index); + final int indexInPage = indexInPage(index); + final double[] page = pages[pageIndex]; + final double ret = page[indexInPage]; + page[indexInPage] = value; + return ret; + } + + @Override + public double increment(long index, double inc) { + final int pageIndex = pageIndex(index); + final int indexInPage = indexInPage(index); + return pages[pageIndex][indexInPage] += inc; + } + + @Override + protected int numBytesPerElement() { + return RamUsageEstimator.NUM_BYTES_INT; + } + + /** Change the size of this array. Content between indexes <code>0</code> and <code>min(size(), newSize)</code> will be preserved. */ + public void resize(long newSize) { + final int numPages = numPages(newSize); + if (numPages > pages.length) { + pages = Arrays.copyOf(pages, ArrayUtil.oversize(numPages, RamUsageEstimator.NUM_BYTES_OBJECT_REF)); + } + for (int i = numPages - 1; i >= 0 && pages[i] == null; --i) { + pages[i] = newDoublePage(i); + } + for (int i = numPages; i < pages.length && pages[i] != null; ++i) { + pages[i] = null; + releasePage(i); + } + this.size = newSize; + } + + @Override + public void fill(long fromIndex, long toIndex, double value) { + Preconditions.checkArgument(fromIndex <= toIndex); + final int fromPage = pageIndex(fromIndex); + final int toPage = pageIndex(toIndex - 1); + if (fromPage == toPage) { + Arrays.fill(pages[fromPage], indexInPage(fromIndex), indexInPage(toIndex - 1) + 1, value); + } else { + Arrays.fill(pages[fromPage], indexInPage(fromIndex), pages[fromPage].length, value); + for (int i = fromPage + 1; i < toPage; ++i) { + Arrays.fill(pages[i], value); + } + Arrays.fill(pages[toPage], 0, indexInPage(toIndex - 1) + 1, value); + } + } + +} |