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

com.yahoo.bard.webservice.metadata.DataSourceMetadata Maven / Gradle / Ivy

Go to download

Fili web service library provides core capabilities for RESTful aggregation navigation, query planning and metadata

There is a newer version: 1.1.13
Show newest version
// Copyright 2016 Yahoo Inc.
// Licensed under the terms of the Apache license. Please see LICENSE.md file distributed with this work for terms.
package com.yahoo.bard.webservice.metadata;

import static com.yahoo.bard.webservice.data.Columns.DIMENSIONS;
import static com.yahoo.bard.webservice.data.Columns.METRICS;

import com.yahoo.bard.webservice.data.Columns;
import com.yahoo.bard.webservice.util.SimplifiedIntervalList;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;

import org.joda.time.DateTime;
import org.joda.time.Interval;

import io.druid.timeline.DataSegment;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * The segment metadata from a particular physical table/druid data source.
 */
public class DataSourceMetadata {
    private final String name;
    private final Map properties;
    private final List segments;

    /**
     * Store the full metadata for a druid data source, mainly as a list of segments.
     *
     * @param name  The name of the druid datasource.
     * @param properties  The map of properties of this datasource.
     * @param segments  The list of segments of this datasource.
     */
    @JsonCreator
    public DataSourceMetadata(
            @JsonProperty("name") String name,
            @JsonProperty("properties") Map properties,
            @JsonProperty("segments") List segments
    ) {
        this.name = name;
        this.properties = ImmutableMap.copyOf(properties);
        this.segments = ImmutableList.copyOf(segments);
    }

    /**
     * Get the name of this datasource.
     *
     * @return The name of the datasource.
     */
    public String getName() {
        return name;
    }

    /**
     * Get the properties of the datasource.
     *
     * @return The map of the properties of the datasource.
     */
    public Map getProperties() {
        return properties;
    }

    /**
     * Get the segments of the datasource.
     *
     * @return The list of the segments of the datasource.
     */
    public List getSegments() {
        return segments;
    }

    /**
     * Return a pair of maps containing the simplified intervals for dimensions and metrics respectively.
     *
     * @param metadata  The metadata that contain segment availability.
     *
     * @return A pair of two maps of simplified intervals. One entry is for dimensions and the other for metrics.
     */
    public static Map> getIntervalLists(DataSourceMetadata metadata) {

        Map> unsortedDimensionIntervals = new HashMap<>();
        Map> unsortedMetricIntervals = new HashMap<>();

        metadata.segments.stream()
                .forEach(
                        segment -> {
                            buildIntervalSet(
                                    segment.getDimensions(),
                                    segment.getInterval(),
                                    unsortedDimensionIntervals
                            );
                            buildIntervalSet(segment.getMetrics(), segment.getInterval(), unsortedMetricIntervals);
                        }
                );


        EnumMap> intervals = new EnumMap<>(Columns.class);
        intervals.put(DIMENSIONS, toSimplifiedIntervalMap(unsortedDimensionIntervals));
        intervals.put(METRICS, toSimplifiedIntervalMap(unsortedMetricIntervals));

        return intervals;
    }

    /**
     * Build the set of intervals for the entries.
     *
     * @param entries  Entries to build the intervals for
     * @param interval  Interval to add to each of the entries
     * @param container  Map into which to build the interval sets
     */
    private static void buildIntervalSet(
            List entries,
            Interval interval,
            Map> container
    ) {
        entries.stream()
                .map(entry -> container.computeIfAbsent(entry, ignored -> new LinkedHashSet<>()))
                .forEach(set -> set.add(interval));
    }

    /**
     * Convert the map of unsorted intervals into a map of SimplifiedIntervalLists.
     *
     * @param unsortedIntervals  Map to clean up
     *
     * @return the cleaned up map
     */
    private static Map toSimplifiedIntervalMap(
            Map> unsortedIntervals
    ) {
        return unsortedIntervals.entrySet().stream()
                .collect(
                        Collectors.toMap(
                                Map.Entry::getKey,
                                entry -> new SimplifiedIntervalList(entry.getValue())
                        )
                );
    }

    /**
     * Return a pair of maps containing the ranges of availability for dimensions and metrics respectively.
     *
     * @param metadata  The metadata that contain segment availability.
     *
     * @return A pair of two maps of range sets. One entry is for dimensions and the other for metrics.
     */
    public static Map>> getRangeLists(DataSourceMetadata metadata) {

        final Map> dimensionIntervals = new HashMap<>();
        final Map> metricIntervals = new HashMap<>();

        metadata.segments.stream()
                .forEach(
                        segment -> {
                            buildRangeSet(segment.getDimensions(), segment.getInterval(), dimensionIntervals);
                            buildRangeSet(segment.getMetrics(), segment.getInterval(), metricIntervals);
                        }
                );

        EnumMap>> intervals = new EnumMap<>(Columns.class);
        intervals.put(DIMENSIONS, dimensionIntervals);
        intervals.put(METRICS, metricIntervals);

        return intervals;
    }

    /**
     * Build the range set of intervals for the entries.
     *
     * @param entries  Entries to build the intervals for
     * @param interval  Interval to add to each of the entries
     * @param container  Map into which to build the interval sets
     */
    private static void buildRangeSet(
            List entries,
            Interval interval,
            Map> container
    ) {
        entries.stream()
                .map(entry -> container.computeIfAbsent(entry, ignored -> TreeRangeSet.create()))
                .forEach(set -> set.add(Range.closedOpen(interval.getStart(), interval.getEnd())));
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) { return true; }
        if (!(o instanceof DataSourceMetadata)) { return false; }

        DataSourceMetadata that = (DataSourceMetadata) o;

        return
                Objects.equals(name, that.name) &&
                Objects.equals(properties, that.properties) &&
                Objects.equals(segments, that.segments);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, properties, segments);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy