001/* Copyright (C) 2013 TU Dortmund
002 * This file is part of AutomataLib, http://www.automatalib.net/.
003 * 
004 * AutomataLib is free software; you can redistribute it and/or
005 * modify it under the terms of the GNU Lesser General Public
006 * License version 3.0 as published by the Free Software Foundation.
007 * 
008 * AutomataLib is distributed in the hope that it will be useful,
009 * but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
011 * Lesser General Public License for more details.
012 * 
013 * You should have received a copy of the GNU Lesser General Public
014 * License along with AutomataLib; if not, see
015 * http://www.gnu.de/documents/lgpl.en.html.
016 */
017package net.automatalib.commons.util.array;
018
019
020/**
021 * Class that provides a resizable <tt>int</tt> array storage.
022 * 
023 * @author Malte Isberner <malte.isberner@gmail.com>
024 *
025 */
026public final class ResizingIntArray {
027        
028        /**
029         * The arrays default initial capacity.
030         */
031        public static final int DEFAULT_INITIAL_CAPACITY = 10;
032        
033        /**
034         * The storage array.
035         */
036        public int[] array;
037        
038        private int nextCapacityHint;
039        
040        
041        /**
042         * Constructor. Initializes an array of the default initial capacity.
043         * @see #DEFAULT_INITIAL_CAPACITY
044         */
045        public ResizingIntArray() {
046                this(DEFAULT_INITIAL_CAPACITY);
047        }
048        
049        /**
050         * Constructor. Creates an array with the specified initial capacity.
051         * 
052         * @param initialCapacity the initial capacity.
053         */
054        public ResizingIntArray(int initialCapacity) {
055                if(initialCapacity <= 0)
056                        initialCapacity = DEFAULT_INITIAL_CAPACITY;
057                this.array = new int[initialCapacity];
058        }
059        
060        /**
061         * Hints the next required capacity. The next time the array is resized, it
062         * is resized to (at least) this capacity.
063         * @param nextCapacityHint the next capacity hint.
064         */
065        public void hintNextCapacity(int nextCapacityHint) {
066                this.nextCapacityHint = nextCapacityHint;
067        }
068        
069        
070        public boolean ensureCapacity(int minCapacity) {
071                if (minCapacity <= array.length)
072                        return false;
073
074                int newCapacity = (array.length * 3) / 2 + 1;
075                if (newCapacity < nextCapacityHint)
076                        newCapacity = nextCapacityHint;
077
078                if (newCapacity < minCapacity)
079                        newCapacity = minCapacity;
080
081                int[] newArray = new int[newCapacity];
082                System.arraycopy(array, 0, newArray, 0, array.length);
083                array = newArray;
084                nextCapacityHint = 0;
085                return true;
086        }
087        
088        public boolean shrink(int maxCapacity) {
089                if(maxCapacity >= array.length)
090                        return false;
091                
092                int[] newArray = new int[maxCapacity];
093                System.arraycopy(array, 0, newArray, 0, maxCapacity);
094                array = newArray;
095                return true;
096        }
097
098        /**
099         * Sets all the elements in the array to the specified value.
100         * @param value the value.
101         */
102        public void setAll(int value) {
103                for(int i = 0; i < array.length; i++)
104                        array[i] = value;
105        }
106        
107        public void swap(ResizingIntArray other) {
108                int[] arrayTmp = array;
109                int hintTmp = nextCapacityHint;
110                array = other.array;
111                nextCapacityHint = other.nextCapacityHint;
112                other.array = arrayTmp;
113                other.nextCapacityHint = hintTmp;
114        }
115        
116        
117}