hollow/src/main/java/com/netflix/hollow/core/index/HollowHashIndexBuilder.java
private long calculateDedupedSizesAndTotalNumberOfSelectBuckets(MultiLinkedElementArray elementArray, GrowingSegmentedLongArray matchIndexHashAndSizeArray) {
        long totalBuckets = 0;
        long maxSize = 0;
        int[] selectArray = new int[8];

        for(int i=0;i<elementArray.numLists();i++) {
            int listSize = elementArray.listSize(i);
            int setSize = 0;
            int predictedBuckets = HashCodes.hashTableSize(listSize);
            int hashMask = predictedBuckets - 1;
            if(predictedBuckets > selectArray.length)
                selectArray = new int[predictedBuckets];
            for(int j=0;j<predictedBuckets;j++)
                selectArray[j] = -1;

            HollowOrdinalIterator iter = elementArray.iterator(i);
            int selectOrdinal = iter.next();
            while(selectOrdinal != HollowOrdinalIterator.NO_MORE_ORDINALS) {
                int hash = HashCodes.hashInt(selectOrdinal);
                int bucket = hash & hashMask;

                while(true) {
                    if(selectArray[bucket] == selectOrdinal)
                        break;
                    if(selectArray[bucket] == -1) {
                        selectArray[bucket] = selectOrdinal;
                        setSize++;
                        break;
                    }

                    bucket = (bucket+1) & hashMask;
                }

                selectOrdinal = iter.next();
            }

            long matchIndexHashAndSize = matchIndexHashAndSizeArray.get(i);
            matchIndexHashAndSize |= (long)setSize << 32;
            matchIndexHashAndSizeArray.set(i, matchIndexHashAndSize);

            totalBuckets += HashCodes.hashTableSize(setSize);
            if(setSize > maxSize)
                maxSize = setSize;
        }

        return totalBuckets | (long)bitsRequiredToRepresentValue(maxSize) << 56;
    }
private long calculateDedupedSizesAndTotalNumberOfSelectBuckets(MultiLinkedElementArray elementArray, GrowingSegmentedLongArray matchIndexHashAndSizeArray) {
        long totalBuckets = 0;
        long maxSize = 0;
        int[] selectArray = new int[8];

        for(int i=0;i<elementArray.numLists();i++) {
            int listSize = elementArray.listSize(i);
            int setSize = 0;
            int predictedBuckets = HashCodes.hashTableSize(listSize);
            int hashMask = predictedBuckets - 1;
            if(predictedBuckets > selectArray.length)
                selectArray = new int[predictedBuckets];
            for(int j=0;j<predictedBuckets;j++)
                selectArray[j] = -1;

            HollowOrdinalIterator iter = elementArray.iterator(i);
            int selectOrdinal = iter.next();
            while(selectOrdinal != HollowOrdinalIterator.NO_MORE_ORDINALS) {
                int hash = HashCodes.hashInt(selectOrdinal);
                int bucket = hash & hashMask;

                while(true) {
                    if(selectArray[bucket] == selectOrdinal)
                        break;
                    if(selectArray[bucket] == -1) {
                        selectArray[bucket] = selectOrdinal;
                        setSize++;
                        break;
                    }

                    bucket = (bucket+1) & hashMask;
                }

                selectOrdinal = iter.next();
            }

            long matchIndexHashAndSize = matchIndexHashAndSizeArray.get(i);
            matchIndexHashAndSize |= (long)setSize << 32;
            matchIndexHashAndSizeArray.set(i, matchIndexHashAndSize);

            totalBuckets += HashCodes.hashTableSize(setSize);
            if(setSize > maxSize)
                maxSize = setSize;
        }

        return totalBuckets | (long)bitsRequiredToRepresentValue(maxSize) << 56;
    }
Called after initial pass.
Returns the sum total number of select buckets in the low 7 bytes, and the bits required for the max set size in the high 1 byte.