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

com.datastax.driver.core.DirectedGraph Maven / Gradle / Ivy

Go to download

A driver for DataStax Enterprise (DSE) and Apache Cassandra 1.2+ clusters that works exclusively with the Cassandra Query Language version 3 (CQL3) and Cassandra's binary protocol, supporting DSE-specific features such as geospatial types, DSE Graph and DSE authentication.

There is a newer version: 2.4.0
Show newest version
/*
 *      Copyright (C) 2012-2017 DataStax Inc.
 *
 *      This software can be used solely with DataStax Enterprise. Please consult the license at
 *      http://www.datastax.com/terms/datastax-dse-driver-license-terms
 */
package com.datastax.driver.core;

import com.datastax.driver.core.exceptions.DriverInternalError;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;

import java.util.*;

/**
 * A basic directed graph implementation to perform topological sorts.
 */
class DirectedGraph {

    // We need to keep track of the predecessor count. For simplicity, use a map to store it alongside the vertices.
    final Map vertices;
    final Multimap adjacencyList;
    boolean wasSorted;

    DirectedGraph(List vertices) {
        this.vertices = Maps.newHashMapWithExpectedSize(vertices.size());
        this.adjacencyList = HashMultimap.create();

        for (V vertex : vertices) {
            this.vertices.put(vertex, 0);
        }
    }

    DirectedGraph(V... vertices) {
        this(Arrays.asList(vertices));
    }

    /**
     * this assumes that {@code from} and {@code to} were part of the vertices passed to the constructor
     */
    void addEdge(V from, V to) {
        Preconditions.checkArgument(vertices.containsKey(from) && vertices.containsKey(to));
        adjacencyList.put(from, to);
        vertices.put(to, vertices.get(to) + 1);
    }

    /**
     * one-time use only, calling this multiple times on the same graph won't work
     */
    List topologicalSort() {
        Preconditions.checkState(!wasSorted);
        wasSorted = true;

        Queue queue = new LinkedList();

        for (Map.Entry entry : vertices.entrySet()) {
            if (entry.getValue() == 0)
                queue.add(entry.getKey());
        }

        List result = Lists.newArrayList();
        while (!queue.isEmpty()) {
            V vertex = queue.remove();
            result.add(vertex);
            for (V successor : adjacencyList.get(vertex)) {
                if (decrementAndGetCount(successor) == 0)
                    queue.add(successor);
            }
        }

        if (result.size() != vertices.size())
            throw new DriverInternalError("failed to perform topological sort, graph has a cycle");

        return result;
    }

    private int decrementAndGetCount(V vertex) {
        Integer count = vertices.get(vertex);
        count = count - 1;
        vertices.put(vertex, count);
        return count;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy