diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 | 
| commit | cf099d11218cb6f6c5cce947d6738e347f07fb12 (patch) | |
| tree | d2b61ce94e654cb01a254d2195259db5f9cc3f3c /lib/Support/IntervalMap.cpp | |
| parent | 49011b52fcba02a6051957b84705159f52fae4e4 (diff) | |
Notes
Diffstat (limited to 'lib/Support/IntervalMap.cpp')
| -rw-r--r-- | lib/Support/IntervalMap.cpp | 161 | 
1 files changed, 161 insertions, 0 deletions
diff --git a/lib/Support/IntervalMap.cpp b/lib/Support/IntervalMap.cpp new file mode 100644 index 0000000000000..4dfcc404ca428 --- /dev/null +++ b/lib/Support/IntervalMap.cpp @@ -0,0 +1,161 @@ +//===- lib/Support/IntervalMap.cpp - A sorted interval map ----------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the few non-templated functions in IntervalMap. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/IntervalMap.h" + +namespace llvm { +namespace IntervalMapImpl { + +void Path::replaceRoot(void *Root, unsigned Size, IdxPair Offsets) { +  assert(!path.empty() && "Can't replace missing root"); +  path.front() = Entry(Root, Size, Offsets.first); +  path.insert(path.begin() + 1, Entry(subtree(0), Offsets.second)); +} + +NodeRef Path::getLeftSibling(unsigned Level) const { +  // The root has no siblings. +  if (Level == 0) +    return NodeRef(); + +  // Go up the tree until we can go left. +  unsigned l = Level - 1; +  while (l && path[l].offset == 0) +    --l; + +  // We can't go left. +  if (path[l].offset == 0) +    return NodeRef(); + +  // NR is the subtree containing our left sibling. +  NodeRef NR = path[l].subtree(path[l].offset - 1); + +  // Keep right all the way down. +  for (++l; l != Level; ++l) +    NR = NR.subtree(NR.size() - 1); +  return NR; +} + +void Path::moveLeft(unsigned Level) { +  assert(Level != 0 && "Cannot move the root node"); + +  // Go up the tree until we can go left. +  unsigned l = 0; +  if (valid()) { +    l = Level - 1; +    while (path[l].offset == 0) { +      assert(l != 0 && "Cannot move beyond begin()"); +      --l; +    } +  } else if (height() < Level) +    // end() may have created a height=0 path. +    path.resize(Level + 1, Entry(0, 0, 0)); + +  // NR is the subtree containing our left sibling. +  --path[l].offset; +  NodeRef NR = subtree(l); + +  // Get the rightmost node in the subtree. +  for (++l; l != Level; ++l) { +    path[l] = Entry(NR, NR.size() - 1); +    NR = NR.subtree(NR.size() - 1); +  } +  path[l] = Entry(NR, NR.size() - 1); +} + +NodeRef Path::getRightSibling(unsigned Level) const { +  // The root has no siblings. +  if (Level == 0) +    return NodeRef(); + +  // Go up the tree until we can go right. +  unsigned l = Level - 1; +  while (l && atLastEntry(l)) +    --l; + +  // We can't go right. +  if (atLastEntry(l)) +    return NodeRef(); + +  // NR is the subtree containing our right sibling. +  NodeRef NR = path[l].subtree(path[l].offset + 1); + +  // Keep left all the way down. +  for (++l; l != Level; ++l) +    NR = NR.subtree(0); +  return NR; +} + +void Path::moveRight(unsigned Level) { +  assert(Level != 0 && "Cannot move the root node"); + +  // Go up the tree until we can go right. +  unsigned l = Level - 1; +  while (l && atLastEntry(l)) +    --l; + +  // NR is the subtree containing our right sibling. If we hit end(), we have +  // offset(0) == node(0).size(). +  if (++path[l].offset == path[l].size) +    return; +  NodeRef NR = subtree(l); + +  for (++l; l != Level; ++l) { +    path[l] = Entry(NR, 0); +    NR = NR.subtree(0); +  } +  path[l] = Entry(NR, 0); +} + + +IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity, +                   const unsigned *CurSize, unsigned NewSize[], +                   unsigned Position, bool Grow) { +  assert(Elements + Grow <= Nodes * Capacity && "Not enough room for elements"); +  assert(Position <= Elements && "Invalid position"); +  if (!Nodes) +    return IdxPair(); + +  // Trivial algorithm: left-leaning even distribution. +  const unsigned PerNode = (Elements + Grow) / Nodes; +  const unsigned Extra = (Elements + Grow) % Nodes; +  IdxPair PosPair = IdxPair(Nodes, 0); +  unsigned Sum = 0; +  for (unsigned n = 0; n != Nodes; ++n) { +    Sum += NewSize[n] = PerNode + (n < Extra); +    if (PosPair.first == Nodes && Sum > Position) +      PosPair = IdxPair(n, Position - (Sum - NewSize[n])); +  } +  assert(Sum == Elements + Grow && "Bad distribution sum"); + +  // Subtract the Grow element that was added. +  if (Grow) { +    assert(PosPair.first < Nodes && "Bad algebra"); +    assert(NewSize[PosPair.first] && "Too few elements to need Grow"); +    --NewSize[PosPair.first]; +  } + +#ifndef NDEBUG +  Sum = 0; +  for (unsigned n = 0; n != Nodes; ++n) { +    assert(NewSize[n] <= Capacity && "Overallocated node"); +    Sum += NewSize[n]; +  } +  assert(Sum == Elements && "Bad distribution sum"); +#endif + +  return PosPair; +} + +} // namespace IntervalMapImpl +} // namespace llvm +  | 
