Skip to content

Commit

Permalink
- FastArray.resize() now uses the same grow algorithm as ArrayList (n…
Browse files Browse the repository at this point in the history
…ew capacity=old capacity *1.5)
  • Loading branch information
belaban committed Oct 15, 2024
1 parent ff346f1 commit 667adbf
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 30 deletions.
46 changes: 23 additions & 23 deletions src/org/jgroups/util/FastArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class FastArray<T> implements Iterable<T>, List<T> {
protected T[] elements;
protected int index; // position at which the next element is inserted; only increments, never decrements
protected int size; // size: basically index - null elements
protected int increment=5;
protected int increment; // if 0, use the built-in resize (new capacity: old capacity * 1.5)
protected int print_limit=20; // max numnber of elements to be printed in toString

public FastArray(int capacity) {
Expand All @@ -33,7 +33,7 @@ public FastArray(T[] elements, int index) {
public int size() {return size;}
public boolean isEmpty() {return size == 0;}
public int increment() {return increment;}
public FastArray<T> increment(int i) {this.increment=ensurePositive(i); return this;}
public FastArray<T> increment(int i) {this.increment=i; return this;}
public int printLimit() {return print_limit;}
public FastArray<T> printLimit(int l) {this.print_limit=l; return this;}

Expand All @@ -48,7 +48,7 @@ public boolean add(T el, boolean resize) {
if(index == elements.length) {
if(!resize)
return false;
resize(index + increment);
resize(index +1);
}
elements[index++]=el;
size++;
Expand All @@ -59,7 +59,7 @@ public boolean add(T el, boolean resize) {
public void add(int idx, T el) {
checkIndex(idx);
if(index+1 > elements.length)
resize(index + 1 + increment);
resize(index +1);

System.arraycopy(elements, idx,
elements, idx+1,
Expand All @@ -82,7 +82,7 @@ public boolean addAll(T[] els, int length) {
if(length > els.length)
length=els.length;
if(index + length > elements.length)
resize(index + length + increment);
resize(index + length);
System.arraycopy(els, 0, elements, index, length);
int added=0, end_index=index+length;
while(index < end_index) {
Expand All @@ -104,7 +104,7 @@ public boolean addAll(Collection<? extends T> list) {
return false;
int list_size=list.size();
if(index + list_size > elements.length)
resize(index + list_size + increment);
resize(index + list_size);
int old_size=size;
for(T el: list) {
if(el != null) { // null elements need to be handled
Expand All @@ -126,7 +126,7 @@ public boolean addAll(FastArray<T> fa, boolean resize) {
throw new IllegalArgumentException("cannot add FastArray to itself");
int fa_size=fa.size();
if(index+fa_size > elements.length && resize)
resize(index + fa_size + increment);
resize(index + fa_size);
int old_size=size;
for(T el: fa) {
if(index >= elements.length)
Expand Down Expand Up @@ -174,15 +174,13 @@ public boolean addAll(int idx, Collection<? extends T> c) {
* @return The number of non-null elements transferred from other
*/
public int transferFrom(FastArray<T> other, boolean clear) {
if(other == null || this == other)
if(other == null || this == other || other.isEmpty())
return 0;
int capacity=elements.length, other_size=other.size(), other_capacity=other.capacity();
if(other_size == 0)
return 0;
if(capacity < other_capacity)
elements=Arrays.copyOf(other.elements, other_capacity);
int capacity=elements.length, other_index=other.index(), other_size=other.size();
if(capacity < other_index)
elements=Arrays.copyOf(other.elements, other_index);
else
System.arraycopy(other.elements, 0, this.elements, 0, other_capacity);
System.arraycopy(other.elements, 0, this.elements, 0, other_index);
if(this.index > other.index)
for(int i=other.index; i < this.index; i++)
elements[i]=null;
Expand Down Expand Up @@ -339,7 +337,7 @@ public boolean retainAll(Collection<?> c) {

@Override
public void clear() {
clear(false);
clear(true);
}

public FastArray<T> clear(boolean null_elements) {
Expand Down Expand Up @@ -411,11 +409,19 @@ public String print() {
public FastArray<T> resize(int new_capacity) {
if(new_capacity <= elements.length)
return this;
elements=Arrays.copyOf(elements, new_capacity);
int new_cap;
if(increment > 0)
new_cap=new_capacity+increment;
else {
int old_capacity=elements.length;
int min_growth=new_capacity - old_capacity;
int preferred_growth=old_capacity >> 1; // 50% of the old capacity
new_cap=old_capacity + Math.max(min_growth, preferred_growth);
}
elements=Arrays.copyOf(elements, new_cap);
return this;
}


protected String print(int limit) {
boolean first=true;
StringBuilder sb=new StringBuilder();
Expand All @@ -433,12 +439,6 @@ protected String print(int limit) {
return sb.toString();
}

protected static int ensurePositive(int i) {
if(i < 1)
throw new IllegalArgumentException("value needs to be >= 1");
return i;
}

protected int checkIndex(int idx) {
if(idx > index || idx < 0)
throw new IndexOutOfBoundsException(String.format("0 >= idx (%d) < index (%d)", idx, index));
Expand Down
28 changes: 21 additions & 7 deletions tests/junit-functional/org/jgroups/tests/FastArrayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,15 @@ public void testAddAllWithIndex() {
}

public void testAddList() {
FastArray<Integer> fa=create(3);
FastArray<Integer> fa=create(3).increment(5);
List<Integer> list=Arrays.asList(3, 4, 5, 6, 7, 8, 9);
assert fa.size() == 3;
boolean added=fa.addAll(list);
assert added;
assert fa.size() == 10;
assert fa.capacity() == 10 + fa.increment();

fa=new FastArray<>(10);
fa=new FastArray<Integer>(10).increment(2);
added=fa.addAll(Arrays.asList(0, 1, 2));
assert added;
added=fa.addAll(list);
Expand All @@ -156,13 +156,13 @@ public void testAddList() {
added=fa.add(11);
assert added;
assert fa.size() == 11;
assert fa.capacity() == 10 + fa.increment();
assert fa.capacity() == 11 + fa.increment();

list=new ArrayList<>();
added=fa.addAll(list);
assert !added;
assert fa.size() == 11;
assert fa.capacity() == 10 + fa.increment();
assert fa.capacity() == 11 + fa.increment();
}

public void testAddFastArray() {
Expand Down Expand Up @@ -537,13 +537,27 @@ public void testGet() {
}

public void testResize() {
FastArray<Integer> fa=create(2);
FastArray<Integer> fa=create(2).increment(4);
int old_cap=fa.capacity();
assert fa.capacity() == old_cap;
fa.add(3);
assert fa.capacity() == old_cap + fa.increment();
assert fa.capacity() == old_cap + 1 + fa.increment();
}

public void testResize2() {
FastArray<Integer> fa=create(128);
assert fa.capacity() == 128;
fa.add(128);
int new_capacity=fa.capacity() + fa.capacity() >> 1;
assert fa.capacity() == new_capacity;
IntStream.rangeClosed(128,192).forEach(fa::add);
new_capacity=fa.capacity() + fa.capacity() >> 1;
assert fa.capacity() == new_capacity;
IntStream.rangeClosed(129,288).forEach(fa::add);
new_capacity=fa.capacity() + fa.capacity() >> 1;
assert fa.capacity() == new_capacity;
}


public void testSimpleIteration() {
FastArray<Integer> fa=create(10);
List<Integer> l=new ArrayList<>(10);
Expand Down

0 comments on commit 667adbf

Please sign in to comment.