All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.elasticsearch.cluster.metadata.DiffableStringMap Maven / Gradle / Ivy

There is a newer version: 8.14.0
Show newest version
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

package org.elasticsearch.cluster.metadata;

import org.elasticsearch.cluster.Diff;
import org.elasticsearch.cluster.Diffable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

import java.io.IOException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * This is a {@code Map} that implements AbstractDiffable so it
 * can be used for cluster state purposes
 */
public class DiffableStringMap extends AbstractMap implements Diffable {

    public static final DiffableStringMap EMPTY = new DiffableStringMap(Collections.emptyMap());

    private final Map innerMap;

    @SuppressWarnings("unchecked")
    public static DiffableStringMap readFrom(StreamInput in) throws IOException {
        final Map map = (Map) in.readMap();
        return map.isEmpty() ? EMPTY : new DiffableStringMap(map);
    }

    DiffableStringMap(final Map map) {
        this.innerMap = Collections.unmodifiableMap(map);
    }

    @Override
    public Set> entrySet() {
        return innerMap.entrySet();
    }

    @Override
    public String get(Object key) {
        return innerMap.get(key);
    }

    @Override
    public boolean containsKey(Object key) {
        return innerMap.containsKey(key);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void writeTo(StreamOutput out) throws IOException {
        out.writeGenericMap((Map) (Map) innerMap);
    }

    @Override
    public Diff diff(DiffableStringMap previousState) {
        if (equals(previousState)) {
            return DiffableStringMapDiff.EMPTY;
        }
        final List tempDeletes = new ArrayList<>();
        for (String key : previousState.keySet()) {
            if (containsKey(key) == false) {
                tempDeletes.add(key);
            }
        }

        final Map tempUpserts = new HashMap<>();
        for (Map.Entry partIter : entrySet()) {
            String beforePart = previousState.get(partIter.getKey());
            if (beforePart == null) {
                tempUpserts.put(partIter.getKey(), partIter.getValue());
            } else if (partIter.getValue().equals(beforePart) == false) {
                tempUpserts.put(partIter.getKey(), partIter.getValue());
            }
        }
        return getDiff(tempDeletes, tempUpserts);
    }

    public static Diff readDiffFrom(StreamInput in) throws IOException {
        final List deletes = in.readStringList();
        final Map upserts = in.readMap(StreamInput::readString, StreamInput::readString);
        return getDiff(deletes, upserts);
    }

    private static Diff getDiff(List deletes, Map upserts) {
        if (deletes.isEmpty() && upserts.isEmpty()) {
            return DiffableStringMapDiff.EMPTY;
        }
        return new DiffableStringMapDiff(deletes, upserts);
    }

    /**
     * Represents differences between two DiffableStringMaps.
     */
    public static class DiffableStringMapDiff implements Diff {

        public static final DiffableStringMapDiff EMPTY = new DiffableStringMapDiff(List.of(), Map.of()) {
            @Override
            public DiffableStringMap apply(DiffableStringMap part) {
                return part;
            }
        };

        private final List deletes;
        private final Map upserts; // diffs also become upserts

        private DiffableStringMapDiff(List deletes, Map upserts) {
            this.deletes = deletes;
            this.upserts = upserts;
        }

        public List getDeletes() {
            return deletes;
        }

        public static Map> getDiffs() {
            return Collections.emptyMap();
        }

        public Map getUpserts() {
            return upserts;
        }

        @Override
        public void writeTo(StreamOutput out) throws IOException {
            out.writeStringCollection(deletes);
            out.writeMap(upserts, StreamOutput::writeString, StreamOutput::writeString);
        }

        @Override
        public DiffableStringMap apply(DiffableStringMap part) {
            Map builder = new HashMap<>(part.innerMap);
            List deletes = getDeletes();
            for (String delete : deletes) {
                builder.remove(delete);
            }
            assert getDiffs().size() == 0 : "there should never be diffs for DiffableStringMap";

            builder.putAll(upserts);
            return new DiffableStringMap(builder);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy