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

tech.ydb.topic.read.impl.DisjointOffsetRangeSet Maven / Gradle / Ivy

The newest version!
package tech.ydb.topic.read.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

import tech.ydb.topic.description.OffsetsRange;

/**
 * @author Nikolay Perfilov
 */
public class DisjointOffsetRangeSet {
    private final NavigableMap ranges = new TreeMap<>();

    public void add(OffsetsRange rangeToCommit) {
        Map.Entry floorEntry = ranges.floorEntry(rangeToCommit.getStart());
        if (floorEntry != null && floorEntry.getValue().getEnd() > rangeToCommit.getStart()) {
            throwClashesException(floorEntry.getValue(), rangeToCommit);
        }
        Map.Entry ceilingEntry = ranges.ceilingEntry(rangeToCommit.getStart());
        if (ceilingEntry != null && rangeToCommit.getEnd() > ceilingEntry.getValue().getStart()) {
            throwClashesException(ceilingEntry.getValue(), rangeToCommit);
        }
        boolean mergedFloor = false;
        if (floorEntry != null && floorEntry.getValue().getEnd() == rangeToCommit.getStart()) {
            floorEntry.getValue().setEnd(rangeToCommit.getEnd());
            mergedFloor = true;
        }
        if (ceilingEntry != null) {
            OffsetsRangeImpl ceilingValue = ceilingEntry.getValue();
            if (rangeToCommit.getEnd() == ceilingValue.getStart()) {
                ranges.remove(ceilingEntry.getKey());
                if (mergedFloor) {
                    floorEntry.getValue().setEnd(ceilingValue.getEnd());
                } else {
                    ceilingValue.setStart(rangeToCommit.getStart());
                    ranges.put(rangeToCommit.getStart(), ceilingValue);
                }
                return;
            }
        }
        if (!mergedFloor) {
            ranges.put(rangeToCommit.getStart(), new OffsetsRangeImpl(rangeToCommit));
        }
    }

    public List getRangesAndClear() {
        Collection values = ranges.values();
        List result = new ArrayList<>(values);
        values.clear();
        return result;
    }

    private void throwClashesException(OffsetsRangeImpl existingRange, OffsetsRange newRange) {
        String errMessage = "Error adding new offset range. Added range [" +
                newRange.getStart() + "," + newRange.getEnd() + ") clashes with existing range [" +
                existingRange.getStart() + "," + existingRange.getEnd() + ")";
        throw new RuntimeException(errMessage);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy