//===-- sanitizer_bvgraph.h -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of Sanitizer runtime.
// BVGraph -- a directed graph.
//
//===----------------------------------------------------------------------===//

#ifndef SANITIZER_BVGRAPH_H
#define SANITIZER_BVGRAPH_H

#include "sanitizer_common.h"
#include "sanitizer_bitvector.h"

namespace __sanitizer {

// Directed graph of fixed size implemented as an array of bit vectors.
// Not thread-safe, all accesses should be protected by an external lock.
template<class BV>
class BVGraph {
 public:
  enum SizeEnum : uptr { kSize = BV::kSize };
  uptr size() const { return kSize; }
  // No CTOR.
  void clear() {
    for (uptr i = 0; i < size(); i++)
      v[i].clear();
  }

  bool empty() const {
    for (uptr i = 0; i < size(); i++)
      if (!v[i].empty())
        return false;
    return true;
  }

  // Returns true if a new edge was added.
  bool addEdge(uptr from, uptr to) {
    check(from, to);
    return v[from].setBit(to);
  }

  // Returns true if at least one new edge was added.
  uptr addEdges(const BV &from, uptr to, uptr added_edges[],
                uptr max_added_edges) {
    uptr res = 0;
    t1.copyFrom(from);
    while (!t1.empty()) {
      uptr node = t1.getAndClearFirstOne();
      if (v[node].setBit(to))
        if (res < max_added_edges)
          added_edges[res++] = node;
    }
    return res;
  }

  // *EXPERIMENTAL*
  // Returns true if an edge from=>to exist.
  // This function does not use any global state except for 'this' itself,
  // and thus can be called from different threads w/o locking.
  // This would be racy.
  // FIXME: investigate how much we can prove about this race being "benign".
  bool hasEdge(uptr from, uptr to) { return v[from].getBit(to); }

  // Returns true if the edge from=>to was removed.
  bool removeEdge(uptr from, uptr to) {
    return v[from].clearBit(to);
  }

  // Returns true if at least one edge *=>to was removed.
  bool removeEdgesTo(const BV &to) {
    bool res = 0;
    for (uptr from = 0; from < size(); from++) {
      if (v[from].setDifference(to))
        res = true;
    }
    return res;
  }

  // Returns true if at least one edge from=>* was removed.
  bool removeEdgesFrom(const BV &from) {
    bool res = false;
    t1.copyFrom(from);
    while (!t1.empty()) {
      uptr idx = t1.getAndClearFirstOne();
      if (!v[idx].empty()) {
        v[idx].clear();
        res = true;
      }
    }
    return res;
  }

  void removeEdgesFrom(uptr from) {
    return v[from].clear();
  }

  bool hasEdge(uptr from, uptr to) const {
    check(from, to);
    return v[from].getBit(to);
  }

  // Returns true if there is a path from the node 'from'
  // to any of the nodes in 'targets'.
  bool isReachable(uptr from, const BV &targets) {
    BV &to_visit = t1,
       &visited = t2;
    to_visit.copyFrom(v[from]);
    visited.clear();
    visited.setBit(from);
    while (!to_visit.empty()) {
      uptr idx = to_visit.getAndClearFirstOne();
      if (visited.setBit(idx))
        to_visit.setUnion(v[idx]);
    }
    return targets.intersectsWith(visited);
  }

  // Finds a path from 'from' to one of the nodes in 'target',
  // stores up to 'path_size' items of the path into 'path',
  // returns the path length, or 0 if there is no path of size 'path_size'.
  uptr findPath(uptr from, const BV &targets, uptr *path, uptr path_size) {
    if (path_size == 0)
      return 0;
    path[0] = from;
    if (targets.getBit(from))
      return 1;
    // The function is recursive, so we don't want to create BV on stack.
    // Instead of a getAndClearFirstOne loop we use the slower iterator.
    for (typename BV::Iterator it(v[from]); it.hasNext(); ) {
      uptr idx = it.next();
      if (uptr res = findPath(idx, targets, path + 1, path_size - 1))
        return res + 1;
    }
    return 0;
  }

  // Same as findPath, but finds a shortest path.
  uptr findShortestPath(uptr from, const BV &targets, uptr *path,
                        uptr path_size) {
    for (uptr p = 1; p <= path_size; p++)
      if (findPath(from, targets, path, p) == p)
        return p;
    return 0;
  }

 private:
  void check(uptr idx1, uptr idx2) const {
    CHECK_LT(idx1, size());
    CHECK_LT(idx2, size());
  }
  BV v[kSize];
  // Keep temporary vectors here since we can not create large objects on stack.
  BV t1, t2;
};

} // namespace __sanitizer

#endif // SANITIZER_BVGRAPH_H
