public T getLatest()

in modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationChanger.java [316:476]


    public <T> T getLatest(List<KeyPathNode> path) {
        assert !path.isEmpty();
        assert path instanceof RandomAccess : path.getClass();
        assert !path.get(0).unresolvedName : path;

        // This map will be merged into the data from the storage. It's required for the conversion into tree to work.
        // Namely, named list order indexes and names are mandatory for conversion.
        Map<String, Map<String, Serializable>> extras = new HashMap<>();

        // Joiner for the prefix that will be used to fetch data from the storage.
        StringJoiner prefixJoiner = new StringJoiner(KEY_SEPARATOR);

        int pathSize = path.size();

        KeyPathNode lastPathNode = path.get(pathSize - 1);

        // This loop is required to accumulate prefix and resolve all unresolved named list elements' ids.
        for (int idx = 0; idx < pathSize; idx++) {
            KeyPathNode keyPathNode = path.get(idx);

            // Regular keys and resolved ids go straight to the prefix.
            if (!keyPathNode.unresolvedName) {
                // Fake name and 0 index go to extras in case of resolved named list elements.
                if (keyPathNode.namedListEntry) {
                    prefixJoiner.add(keyPathNode.key);

                    String prefix = prefixJoiner + KEY_SEPARATOR;

                    extras.put(prefix, Map.of(
                            prefix + NamedListNode.NAME, "<name_placeholder>",
                            prefix + NamedListNode.ORDER_IDX, 0
                    ));
                } else {
                    prefixJoiner.add(keyPathNode.key);
                }

                continue;
            }

            assert keyPathNode.namedListEntry : path;

            // Here we have unresolved named list element. Name must be translated into the internal id.
            // There's a special path for this purpose in the storage.
            String unresolvedNameKey = prefixJoiner + KEY_SEPARATOR
                    + NamedListNode.IDS + KEY_SEPARATOR
                    + escape(keyPathNode.key);

            // Data from the storage.
            Serializable resolvedName = get(storage.readLatest(unresolvedNameKey));

            if (resolvedName == null) {
                throw new NoSuchElementException(prefixJoiner + KEY_SEPARATOR + escape(keyPathNode.key));
            }

            assert resolvedName instanceof UUID : resolvedName;

            // Resolved internal id from the map.
            UUID internalId = (UUID) resolvedName;

            // There's a chance that this is exactly what user wants. If their request ends with
            // `*.get("resourceName").internalId()` then the result can be returned straight away.
            if (idx == pathSize - 2 && INTERNAL_ID.equals(lastPathNode.key)) {
                assert !lastPathNode.unresolvedName : path;

                // Despite the fact that this cast looks very stupid, it is correct. Internal ids are always UUIDs.
                return (T) internalId;
            }

            prefixJoiner.add(internalId.toString());

            String prefix = prefixJoiner + KEY_SEPARATOR;

            // Real name and 0 index go to extras in case of unresolved named list elements.
            extras.put(prefix, Map.of(
                    prefix + NamedListNode.NAME, keyPathNode.key,
                    prefix + NamedListNode.ORDER_IDX, 0
            ));
        }

        // Exceptional case, the only purpose of it is to ensure that named list element with given internal id does exist.
        // That id must be resolved, otherwise method would already be completed in the loop above.
        if (lastPathNode.key.equals(INTERNAL_ID) && !lastPathNode.unresolvedName && path.get(pathSize - 2).namedListEntry) {
            assert !path.get(pathSize - 2).unresolvedName : path;

            // Not very elegant, I know. <internal_id> is replaced with the <name> in the prefix.
            // <name> always exists in named list element, and it's an easy way to check element's existence.
            String nameStorageKey = prefixJoiner.toString().replaceAll(quote(INTERNAL_ID) + "$", NamedListNode.NAME);

            // Data from the storage.
            Serializable name = get(storage.readLatest(nameStorageKey));

            if (name != null) {
                // Id is already known.
                return (T) UUID.fromString(path.get(pathSize - 2).key);
            } else {
                throw new NoSuchElementException(prefixJoiner.toString());
            }
        }

        String prefix = prefixJoiner.toString();

        // Reading all ids is also a special case.
        if (lastPathNode.key.equals(INTERNAL_IDS) && !lastPathNode.unresolvedName && path.get(pathSize - 1).namedListEntry) {
            prefix = prefix.replaceAll(quote(INTERNAL_IDS) + "$", NamedListNode.IDS + KEY_SEPARATOR);

            Map<String, ? extends Serializable> storageData = get(storage.readAllLatest(prefix));

            return (T) List.copyOf(storageData.values());
        }

        if (lastPathNode.key.equals(INTERNAL_ID) && !path.get(pathSize - 2).namedListEntry) {
            // This is not particularly efficient, but there's no way someone will actually use this case for real outside of tests.
            prefix = prefix.replaceAll(quote(KEY_SEPARATOR + INTERNAL_ID) + "$", "");
        } else if (lastPathNode.key.contains(INJECTED_NAME)) {
            prefix = prefix.replaceAll(quote(KEY_SEPARATOR + INJECTED_NAME), "");
        }

        // Data from the storage.
        Map<String, ? extends Serializable> storageData = get(storage.readAllLatest(prefix));

        // Data to be converted into the tree.
        Map<String, Serializable> mergedData = new HashMap<>();

        if (!storageData.isEmpty()) {
            mergedData.putAll(storageData);

            for (Entry<String, Map<String, Serializable>> extrasEntry : extras.entrySet()) {
                for (String storageKey : storageData.keySet()) {
                    String extrasPrefix = extrasEntry.getKey();

                    if (storageKey.startsWith(extrasPrefix)) {
                        // Add extra order indexes and names before converting it to the tree.
                        for (Entry<String, Serializable> extrasEntryMap : extrasEntry.getValue().entrySet()) {
                            mergedData.putIfAbsent(extrasEntryMap.getKey(), extrasEntryMap.getValue());
                        }

                        break;
                    }
                }
            }

            if (lastPathNode.namedListEntry) {
                // Change element's order index to zero. Conversion won't work if indexes range is not continuous.
                mergedData.put(prefix + KEY_SEPARATOR + NamedListNode.ORDER_IDX, 0);
            }
        }

        // Super root that'll be filled from the storage data.
        InnerNode rootNode = new SuperRoot(rootCreator());

        fillFromPrefixMap(rootNode, toPrefixMap(mergedData));

        // "addDefaults" won't work if regular root is missing.
        if (storageData.isEmpty()) {
            rootNode.construct(path.get(0).key, ConfigurationUtil.EMPTY_CFG_SRC, true);
        }

        addDefaults(rootNode);

        return findEx(path, rootNode);
    }