protected void expand() {
		T[][] old = buckets;
		currentPrime += 4;
		int newCapacity = buckets.length * 2;
		T[][] newTable = createBuckets(newCapacity);
		int[] newBucketLengths = new int[newTable.length];
		buckets = newTable;
		threshold = (int)(newCapacity * LOAD_FACTOR);
//		System.out.println("new size="+newCapacity+", thres="+threshold);
		// rehash all existing entries
		int oldSize = size();
		for (T[] bucket : old) {
			if ( bucket==null ) {
				continue;
			}

			for (T o : bucket) {
				if ( o==null ) {
					break;
				}

				int b = getBucket(o);
				int bucketLength = newBucketLengths[b];
				T[] newBucket;
				if (bucketLength == 0) {
					// new bucket
					newBucket = createBucket(initialBucketCapacity);
					newTable[b] = newBucket;
				}
				else {
					newBucket = newTable[b];
					if (bucketLength == newBucket.length) {
						// expand
						newBucket = Arrays.copyOf(newBucket, newBucket.length * 2);
						newTable[b] = newBucket;
					}
				}

				newBucket[bucketLength] = o;
				newBucketLengths[b]++;
			}
		}

		assert n == oldSize;
	}
Add {@code o} to set if not there; return existing value if already
there. This method performs the same operation as {@link #add} aside from
the return value.
runtime/Java/src/org/antlr/v4/runtime/misc/Array2DHashSet.java