public XodusDirectory()

in lucene-directory-v2/src/main/java/jetbrains/exodus/lucene2/XodusDirectory.java [95:270]


    public XodusDirectory(Environment environment) throws IOException {
        this.environment = (EnvironmentImpl) environment;
        var log = this.environment.getLog();
        var logConfig = log.getConfig();

        var path = Path.of(log.getLocation());

        if (!Files.isDirectory(path)) {
            throw new ExodusException("Path " + path + " does not exist in file system.");
        }

        if (logConfig.isSharedCache()) {
            sharedLogCache = (SharedLogCache) log.cache;
        } else {
            throw new ExodusException("Lucene directory : " + log.getLocation() +
                    " . Only environments with shared cache are supported.");
        }


        this.cipherProvider = logConfig.getCipherProvider();
        this.cipherKey = logConfig.getCipherKey();

        this.identity = Log.Companion.getIdentityGenerator().nextId();

        this.luceneOutputPath = path.resolve("luceneOutput");
        this.luceneIndex = path.resolve("luceneIndex");

        if (Files.exists(luceneOutputPath)) {
            IOUtil.deleteRecursively(luceneOutputPath.toFile());
        }

        if (!environment.computeInTransaction(txn -> environment.storeExists(NAME_TO_ADDRESS_STORE_NAME, txn))) {
            var removalMessage = NAME_TO_ADDRESS_STORE_NAME +
                    " store does not exist. All Lucene index files will be removed.";

            if (Files.exists(luceneIndex)) {
                logger.warn(removalMessage);
                IOUtil.deleteRecursively(luceneIndex.toFile());
            }
        }

        this.nameToAddressStore = environment.computeInTransaction(txn ->
                environment.openStore(NAME_TO_ADDRESS_STORE_NAME, StoreConfig.WITHOUT_DUPLICATES, txn));

        if (!Files.exists(luceneOutputPath)) {
            Files.createDirectory(luceneOutputPath);
        }

        if (!Files.exists(luceneIndex)) {
            Files.createDirectory(luceneIndex);
        }

        var runCheck = ((EnvironmentImpl) environment).isCheckLuceneDirectory();
        LongOpenHashSet storedFiles = new LongOpenHashSet();

        if (runCheck) {
            logger.warn("Xodus directory " + log.getLocation() + " : clearing broken links between files and indexes.");

            var namesToDelete = environment.computeInReadonlyTransaction(txn -> {
                var toDelete = new ArrayList<ByteIterable>();

                try (var cursor = nameToAddressStore.openCursor(txn)) {
                    while (cursor.getNext()) {
                        final var address = LongBinding.entryToLong(cursor.getValue());
                        if (address >= 0) {
                            final var indexFileName = DirUtil.getFileNameByAddress(address);
                            storedFiles.add(address);

                            if (!Files.exists(luceneIndex.resolve(indexFileName))) {
                                var key = cursor.getKey();
                                logger.info("File " + StringBinding.entryToString(key) +
                                        " is absent and will be removed from index.");

                                toDelete.add(key);
                            }
                        } else {
                            var key = cursor.getKey();
                            toDelete.add(key);
                        }
                    }
                }

                return toDelete;
            });

            environment.executeInTransaction(txn -> {
                for (var name : namesToDelete) {
                    nameToAddressStore.delete(txn, name);
                }
            });
        }

        long[] maxAddressLengthIv = new long[]{-1, -1, -1};
        var fetchIvs = cipherKey != null;

        LongOpenHashSet filesToDelete = new LongOpenHashSet();
        try (var fileStream = DirUtil.listLuceneFiles(luceneIndex)) {
            fileStream.forEach(p -> {
                        var indexFile = p.getFileName().toString();
                        var address = DirUtil.getFileAddress(indexFile);

                        if (runCheck && !storedFiles.contains(address)) {
                            logger.info("File " + indexFile + " is absent in index and will be removed.");
                            filesToDelete.add(address);
                            return;
                        }

                        if (address > maxAddressLengthIv[0]) {
                            maxAddressLengthIv[0] = address;
                            try {
                                maxAddressLengthIv[1] = Files.size(p);
                            } catch (IOException e) {
                                throw new ExodusException("Error during fetching of size of file " + p, e);
                            }
                        }

                        if (fetchIvs) {
                            var ivFileName = DirUtil.getIvFileName(indexFile);
                            var ivPath = luceneIndex.resolve(ivFileName);

                            if (Files.exists(ivPath)) {
                                try (var ivStream = new DataInputStream(Files.newInputStream(ivPath))) {
                                    var iv = ivStream.readLong();

                                    if (iv > maxAddressLengthIv[2]) {
                                        maxAddressLengthIv[2] = iv;
                                    }
                                } catch (EOFException eof) {
                                    //ignore
                                } catch (IOException e) {
                                    throw new ExodusException("Can not read iv file " + ivRnd, e);
                                }
                            }
                        }
                    }
            );
        }

        if (!filesToDelete.isEmpty()) {
            var addressIterator = filesToDelete.longIterator();

            while (addressIterator.hasNext()) {
                var address = addressIterator.nextLong();
                var indexFileName = DirUtil.getFileNameByAddress(address);
                var indexFile = luceneIndex.resolve(indexFileName);

                var ivFileName = DirUtil.getIvFileName(indexFileName);
                var ivFile = luceneIndex.resolve(ivFileName);

                try {
                    Files.deleteIfExists(indexFile);
                    Files.deleteIfExists(ivFile);
                } catch (IOException e) {
                    throw new ExodusException("Can not delete file " + indexFile, e);
                }
            }
        }

        this.pageSize = log.getCachePageSize();

        if (maxAddressLengthIv[0] >= 0) {
            var nextAddress = maxAddressLengthIv[0] + maxAddressLengthIv[1];
            var pages = (nextAddress + pageSize - 1) / pageSize;

            if (pages == 0) {
                pages = 1;
            }

            this.nextAddress = new AtomicLong(pages * pageSize);
        } else {
            this.nextAddress = new AtomicLong(0);
        }

        this.ivGen = new AtomicLong(maxAddressLengthIv[2] + 1);
        this.path = path;
    }