public static CachedInstanceIterable createInstance()

in entity-store/src/main/java/jetbrains/exodus/entitystore/iterate/EntityIdArrayCachedInstanceIterableFactory.java [39:180]


    public static CachedInstanceIterable createInstance(@NotNull final PersistentStoreTransaction txn,
                                                        @NotNull final EntityIterableBase source,
                                                        @NotNull final EntityIteratorBase it) {
        try {
            if (!it.hasNext()) {
                return new EmptyCachedInstanceIterable(txn, source);
            } else {
                final IntArrayList typeIds = IntArrayListSpinAllocator.alloc();
                final LongArrayList localIds = LongArrayListSpinAllocator.alloc();
                long min;
                long max;
                try {
                    boolean onlyOneTypeId = true;
                    boolean localSorted = true;
                    if (source.isSortedById()) {
                        int lastTypeId = -1;
                        EntityId id = it.nextId();
                        while (true) {
                            final int nextTypeId;
                            if (id == null) {
                                nextTypeId = NULL_TYPE_ID;
                                localIds.add(0);
                            } else {
                                nextTypeId = id.getTypeId();
                                localIds.add(id.getLocalId());
                            }
                            if (nextTypeId != lastTypeId) {
                                if (lastTypeId != -1) {
                                    onlyOneTypeId = false;
                                    typeIds.add(localIds.size() - 1); // add upper boundary for previous
                                }
                                typeIds.add(nextTypeId);
                                lastTypeId = nextTypeId;
                            }
                            if (!it.hasNext()) {
                                if (!onlyOneTypeId) {
                                    typeIds.add(localIds.size()); // add boundary for last
                                }
                                break;
                            }
                            id = it.nextId();
                        }
                        min = localIds.get(0);
                        max = localIds.get(localIds.size() - 1);
                    } else {
                        int lastTypeId = -1;
                        long lastLocalId = -1;
                        min = Long.MAX_VALUE;
                        max = Long.MIN_VALUE;
                        boolean compact = true;
                        EntityId id = it.nextId();
                        while (true) {
                            final int nextTypeId;
                            final long nextLocalId;
                            if (id == null) {
                                nextTypeId = NULL_TYPE_ID;
                                nextLocalId = 0;
                            } else {
                                nextTypeId = id.getTypeId();
                                nextLocalId = id.getLocalId();
                            }
                            if (localSorted) {
                                if (lastTypeId > nextTypeId || lastTypeId == nextTypeId && lastLocalId > nextLocalId) {
                                    final int length;
                                    if (nextTypeId == NULL_TYPE_ID && (length = localIds.size()) <= 1) {
                                        if (length == 1) { // direct conversion
                                            onlyOneTypeId = false;
                                            localSorted = false;
                                            compact = false;
                                        } else {
                                            typeIds.add(NULL_TYPE_ID);
                                        }
                                        lastLocalId = nextLocalId;
                                    } else {
                                        localSorted = false;
                                    }
                                } else {
                                    lastLocalId = nextLocalId;
                                }
                            }
                            localIds.add(nextLocalId);
                            if (nextLocalId > max) {
                                max = nextLocalId;
                            }
                            if (nextLocalId < min) {
                                min = nextLocalId;
                            }
                            if (compact) {
                                if (localSorted) {
                                    if (nextTypeId > lastTypeId) {
                                        if (lastTypeId != -1) {
                                            onlyOneTypeId = false;
                                            typeIds.add(localIds.size() - 1); // add upper boundary for previous
                                        }
                                        typeIds.add(nextTypeId);
                                    }
                                    lastTypeId = nextTypeId;
                                } else {
                                    if (typeIds.size() > 1 || nextTypeId != lastTypeId) {
                                        onlyOneTypeId = false;
                                        compact = false;
                                        addNextTypeId(nextTypeId, typeIds, localIds);
                                    }
                                }
                            } else {
                                typeIds.add(nextTypeId);
                            }
                            if (!it.hasNext()) {
                                if (compact && !onlyOneTypeId) {
                                    typeIds.add(localIds.size()); // add boundary for last
                                }
                                break;
                            }
                            id = it.nextId();
                        }
                    }
                    if (localSorted) {
                        if (onlyOneTypeId) {
                            return makeSingleTypeSortedIterable(txn, source, it, typeIds, localIds, min, max);
                        } else {
                            return new MultiTypeSortedEntityIdArrayCachedInstanceIterable(
                                txn, source, typeIds.toArray(), localIds.toArray(), it.toSet()
                            );
                        }
                    } else {
                        if (onlyOneTypeId) {
                            return makeSingleTypeUnsortedIterable(txn, source, it, typeIds, localIds, min, max);
                        } else {
                            return new MultiTypeUnsortedEntityIdArrayCachedInstanceIterable(
                                txn, source, typeIds.toArray(), localIds.toArray(), it.toSet()
                            );
                        }
                    }
                } finally {
                    LongArrayListSpinAllocator.dispose(localIds);
                    IntArrayListSpinAllocator.dispose(typeIds);
                }
            }
        } finally {
            it.disposeIfShouldBe();
        }
    }