summaryrefslogtreecommitdiff
path: root/src/main/java/org/elasticsearch/common/util/BigDoubleArray.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/elasticsearch/common/util/BigDoubleArray.java')
-rw-r--r--src/main/java/org/elasticsearch/common/util/BigDoubleArray.java110
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);
+ }
+ }
+
+}