diff src/main/gov/nasa/jpf/util/DynamicIntArray.java @ 0:61d41facf527

initial v8 import (history reset)
author Peter Mehlitz <Peter.C.Mehlitz@nasa.gov>
date Fri, 23 Jan 2015 10:14:01 -0800
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/gov/nasa/jpf/util/DynamicIntArray.java	Fri Jan 23 10:14:01 2015 -0800
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2014, United States Government, as represented by the
+ * Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The Java Pathfinder core (jpf-core) platform is licensed 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 gov.nasa.jpf.util;
+
+import java.util.Iterator;
+
+/**
+ * simplistic dynamic array that differentiates from ArrayList by
+ *  - using chunks instead of exponential growth, thus efficiently dealing
+ *    with sparse arrays
+ *  - managing primitive 'int' types, i.e. not requiring box objects
+ *
+ * the motivation for this class is memory optimization, i.e. space efficient
+ * storage of potentially huge arrays without good a-priori size guesses
+ *
+ * the API of this class is between a primitive array and a AbstractList. It's
+ * not a Collection implementation because it handles primitive types, but the
+ * API could be extended to support iterators and the like.
+ *
+ * NOTE: like standard Collection implementations/arrays, this class is not
+ * synchronized
+ */
+public final class DynamicIntArray implements Iterable<Integer> {
+  final static int DEFAULT_CHUNKBITS = 8;
+  final static int INIT_CHUNKS = 16;
+
+  class DynIntIterator implements Iterator<Integer> {
+    int i;
+    
+    @Override
+	public boolean hasNext() {
+      return (i<size());
+    }
+
+    @Override
+	public Integer next() {
+      return new Integer(get(i++));
+    }
+
+    @Override
+	public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+  
+  /** growth strategy */
+  Growth growth;
+  
+  /** our allocation sizes */
+  int chunkBits;
+  int nPerChunk; // just a cache for (1<<chunkBits)
+  
+  /** mask for index within chunk */
+  int chunkMask;
+  
+  /** the real data. limitations in generics prevent use of E[][] */
+  int[][] data;
+  
+  /** the maximum index set so far */
+  int maxIndex = -1;
+  
+  public DynamicIntArray () {
+    this(Growth.defaultGrowth, DEFAULT_CHUNKBITS, INIT_CHUNKS);
+  }
+
+  public DynamicIntArray (int size) {
+    this(Growth.defaultGrowth, DEFAULT_CHUNKBITS,
+        (size + (1<<DEFAULT_CHUNKBITS)-1) / (1<<DEFAULT_CHUNKBITS));
+  }
+  
+  /**
+   * Creates a DynamicIntArray in which each chunk has 2**chunkBits elements
+   * and initChunks chunks are initially allocated. 
+   */
+  public DynamicIntArray (int chunkBits, int initChunks) {
+    this(Growth.defaultGrowth, chunkBits, initChunks);
+  }
+  
+  public DynamicIntArray (Growth strategy, int chunkBits, int initChunks) {
+    if (chunkBits > 20) throw new IllegalArgumentException();
+    this.chunkBits = chunkBits;
+    nPerChunk = 1<<chunkBits;
+    this.chunkMask = nPerChunk - 1;
+    data = new int[initChunks][];
+    growth = strategy;
+  }
+
+  public int get (int index) {
+    int i = index >> chunkBits;
+    if (i < data.length && data[i] != null) {
+      int j = index & chunkMask;
+      return data[i][j];
+    } else {
+      return 0;
+    }
+  }
+
+  // this is only the max size, not the max index that was accessed/set
+  public int size() {
+    return data.length * nPerChunk;
+  }
+  
+  public int getMaxIndex() {
+    return maxIndex;
+  }
+  
+  public void set (int index, int value) {
+    if (index > maxIndex) {
+      maxIndex = index;
+    }
+    
+    int i = index >> chunkBits;
+    int j = index & chunkMask;
+    
+    if (i >= data.length) {
+      int nChunks = growth.grow(data.length, i+1);
+      int[][] newChunks = new int[nChunks][];
+      System.arraycopy(data, 0, newChunks, 0, data.length);
+      data = newChunks;
+    }
+    if (data[i] == null) {
+      data[i] = new int[nPerChunk];
+    }
+    
+    data[i][j] = value;
+  }
+
+  @Override
+  public String toString() {
+    int length = data.length * nPerChunk;
+    while (length > 1 && get(length-1) == 0) length--;
+
+    StringBuilder sb = new StringBuilder(length);
+    
+    sb.append('{');
+    int l = length-1;
+    for (int i=0; i<l; i++) {
+      sb.append(get(i));
+      sb.append(',');
+    }
+    sb.append(get(l));
+    sb.append('}');
+    
+    return sb.toString();
+  }
+
+  @Override
+  public Iterator<Integer> iterator() {
+    return new DynIntIterator();
+  }
+
+
+  /**************************** debug & test ************
+  public void dump () {
+    int i, j;
+    for (i=0; i<data.length; i++) {
+      System.out.print( "[" + i + "]: ");
+      if (data[i] != null) {
+        System.out.print("{");
+        int l = data[i].length-1;
+        for (j=0; j<l; j++) {
+          System.out.print(data[i][j]);
+          System.out.print(',');
+        }
+        System.out.print( data[i][j]);
+        System.out.println("}");
+      } else {
+        System.out.println( "null");
+      }
+    }
+  }
+
+  public static void main (String[] args) {
+    int i;
+    DynamicIntArray a = new DynamicIntArray(8);
+
+    a.set(0, 42);
+    a.set(13,13);
+    a.set(24, 42);
+
+    a.set(600, -1);
+    System.out.println(a.get(599));
+    System.out.println(a.get(600));
+    
+    System.out.println( "--------- " + a.size());
+    //System.out.println(a);
+    System.out.println(); System.out.println();
+    //a.dump();
+  }
+  
+  ***************************** end debug & test *********/
+}
+