/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

//    The Persistent Red-Black Tree
//
// Implementation is based on an algorithm described in
// Sarnak, N., Tarjan, R., "Planar point location using
// persistent search trees", in Communications of the ACM,
// 1986, Vol.29, Number 7.
//

#include "config.h"
#include <memory.h>
#include <string.h>

#include "vec.h"
#include "PRBTree.h"

#define ASSERT(x)

#define IS_BLACK(x)     ((x)==NULL || (x)->color == Black)
#define IS_RED(x)       ((x)!=NULL && (x)->color == Red)
#define SET_BLACK(x)    if(x) x->color = Black
#define SET_RED(x)      (x)->color = Red

#define D_OPPOSITE(x) (((x)==Left) ? Right : Left )

PRBTree::LMap::LMap (Key_t _key, void *_item)
{
  key = _key;
  item = _item;
  color = Red;
  parent = NULL;
  for (int i = 0; i < NPTRS; i++)
    {
      dir[i] = None;
      chld[i] = NULL;
      time[i] = 0;
    }
};

PRBTree::LMap::LMap (const LMap& lm)
{
  key = lm.key;
  item = lm.item;
  color = lm.color;
  parent = lm.parent;
  for (int i = 0; i < NPTRS; i++)
    {
      dir[i] = None;
      chld[i] = NULL;
      time[i] = 0;
    }
};

PRBTree::PRBTree ()
{
  roots = new Vector<LMap*>;
  root = NULL;
  times = new Vector<Time_t>;
  rtts = (Time_t) 0;
  curts = (Time_t) 0;
  mlist = NULL;
  vals = NULL;
}

PRBTree::~PRBTree ()
{
  while (mlist)
    {
      LMap *lm = mlist;
      mlist = mlist->next;
      delete lm;
    }
  delete times;
  delete roots;
  delete vals;
}

Vector<void *> *
PRBTree::values ()
{
  if (vals == NULL)
    {
      vals = new Vector<void*>;
      for (LMap *lm = mlist; lm; lm = lm->next)
	vals->append (lm->item);
    }
  return vals;
}

PRBTree::LMap *
PRBTree::rb_new_node (Key_t key, void *item)
{
  LMap *lm = new LMap (key, item);
  lm->next = mlist;
  mlist = lm;
  return lm;
}

PRBTree::LMap *
PRBTree::rb_new_node (LMap *lm)
{
  LMap *lmnew = new LMap (*lm);
  lmnew->next = mlist;
  mlist = lmnew;
  return lmnew;
}

PRBTree::LMap *
PRBTree::rb_child (LMap *lm, Direction d, Time_t ts)
{
  if (lm == NULL)
    return NULL;
  for (int i = 0; i < NPTRS; i++)
    {
      if (lm->time[i] > ts)
	continue;
      if (lm->dir[i] == d)
	return lm->chld[i];
      else if (lm->dir[i] == None)
	break;
    }
  return NULL;
}

PRBTree::Direction
PRBTree::rb_which_chld (LMap *lm)
{
  LMap *prnt = lm->parent;
  if (prnt == NULL)
    return None;
  for (int i = 0; i < NPTRS; i++)
    {
      if (prnt->dir[i] == None)
	break;
      if (prnt->chld[i] == lm)
	return (Direction) prnt->dir[i];
    }
  return None;
}

PRBTree::LMap *
PRBTree::rb_neighbor (LMap *lm, Time_t ts)
{
  ASSERT (lm->dir[0] != None);
  Direction d = D_OPPOSITE (lm->dir[0]);
  LMap *y = NULL;
  LMap *next = lm->chld[0];
  while (next)
    {
      y = next;
      next = rb_child (y, d, ts);
    }
  return y;
}

PRBTree::LMap *
PRBTree::rb_copy_node (LMap *lm, Direction d)
{
  LMap *nlm = rb_new_node (lm);
  rb_fix_chld (lm->parent, nlm, rb_which_chld (lm));
  if (d == None)
    {
      d = Left;
      rb_fix_chld (nlm, rb_child (lm, d, curts), d);
    }

  // copy the other child
  Direction dd = D_OPPOSITE (d);
  rb_fix_chld (nlm, rb_child (lm, dd, curts), dd);
  return nlm;
}

PRBTree::LMap *
PRBTree::rb_fix_chld (LMap *prnt, LMap *lm, Direction d)
{

  if (prnt == NULL)
    {
      // fixing root
      ASSERT (d == None);
      if (rtts == curts)
	root = lm;
      else
	{
	  roots->append (root);
	  times->append (rtts);
	  root = lm;
	  rtts = curts;
	}
      if (lm != NULL)
	lm->parent = prnt;
      return prnt;
    }

  // If we already have a d-pointer at time curts, reuse it
  for (int i = 0; prnt->time[i] == curts; i++)
    {
      if (prnt->dir[i] == d)
	{
	  prnt->chld[i] = lm;
	  if (lm != NULL)
	    lm->parent = prnt;
	  return prnt;
	}
    }

  if (prnt->dir[NPTRS - 1] != None)
    prnt = rb_copy_node (prnt, d);
  ASSERT (prnt->dir[NPTRS - 1] == None);

  for (int i = NPTRS - 1; i > 0; i--)
    {
      prnt->dir[i] = prnt->dir[i - 1];
      prnt->chld[i] = prnt->chld[i - 1];
      prnt->time[i] = prnt->time[i - 1];
    }
  prnt->dir[0] = d;
  prnt->chld[0] = lm;
  prnt->time[0] = curts;
  if (lm != NULL)
    lm->parent = prnt;
  return prnt;
}

PRBTree::LMap *
PRBTree::rb_rotate (LMap *x, Direction d)
{
  Direction dd = D_OPPOSITE (d);
  LMap *y = rb_child (x, dd, curts);
  x = rb_fix_chld (x, rb_child (y, d, curts), dd);
  rb_fix_chld (x->parent, y, rb_which_chld (x));
  rb_fix_chld (y, x, d);
  return x;
}

void
PRBTree::rb_remove_fixup (LMap *x, LMap *prnt, Direction d0)
{

  while (IS_BLACK (x) && (x != root))
    {
      Direction d = (x == NULL) ? d0 : rb_which_chld (x);
      Direction dd = D_OPPOSITE (d);
      LMap *y = rb_child (prnt, dd, curts);
      if (IS_RED (y))
	{
	  SET_BLACK (y);
	  SET_RED (prnt);
	  prnt = rb_rotate (prnt, d);
	  y = rb_child (prnt, dd, curts);
	}
      LMap *y_d = rb_child (y, d, curts);
      LMap *y_dd = rb_child (y, dd, curts);
      if (IS_BLACK (y_d) && IS_BLACK (y_dd))
	{
	  SET_RED (y);
	  x = prnt;
	  prnt = x->parent;
	}
      else
	{
	  if (IS_BLACK (y_dd))
	    {
	      SET_BLACK (y_d);
	      SET_RED (y);
	      y = rb_rotate (y, dd);
	      prnt = y->parent->parent;
	      y = rb_child (prnt, dd, curts);
	      y_dd = rb_child (y, dd, curts);
	    }
	  y->color = prnt->color;
	  SET_BLACK (prnt);
	  SET_BLACK (y_dd);
	  prnt = rb_rotate (prnt, d);
	  break;
	}
    }
  SET_BLACK (x);
}

PRBTree::LMap *
PRBTree::rb_locate (Key_t key, Time_t ts, bool low)
{
  LMap *lm;
  Direction d;
  int i, lt, rt;
  int tsz = times->size ();

  if (ts >= rtts)
    lm = root;
  else
    {
      // exponential search
      for (i = 1; i <= tsz; i = i * 2)
	if (times->fetch (tsz - i) <= ts)
	  break;

      if (i <= tsz)
	{
	  lt = tsz - i;
	  rt = tsz - i / 2 - 1;
	}
      else
	{
	  lt = 0;
	  rt = tsz - 1;
	}
      while (lt <= rt)
	{
	  int md = (lt + rt) / 2;
	  if (times->fetch (md) <= ts)
	    lt = md + 1;
	  else
	    rt = md - 1;
	}
      if (rt < 0)
	return NULL;
      lm = roots->fetch (rt);
    }

  LMap *last_lo = NULL;
  LMap *last_hi = NULL;
  while (lm != NULL)
    {
      if (key >= lm->key)
	{
	  last_lo = lm;
	  d = Right;
	}
      else
	{
	  last_hi = lm;
	  d = Left;
	}
      lm = rb_child (lm, d, ts);
    }
  return low ? last_lo : last_hi;
}

//==================================================== Public interface

bool
PRBTree::insert (Key_t key, Time_t ts, void *item)
{
  LMap *lm, *y;
  Direction d, dd;
  if (ts > curts)
    curts = ts;
  else if (ts < curts)
    return false; // can only update the current tree

  // Insert in the tree in the usual way
  y = NULL;
  d = None;
  for (LMap *next = root; next;)
    {
      y = next;
      if (key == y->key)
	{
	  // copy the node with both children
	  lm = rb_copy_node (y, None);
	  // but use the new item
	  lm->item = item;
	  return true;
	}
      d = (key < y->key) ? Left : Right;
      next = rb_child (y, d, curts);
    }
  lm = rb_new_node (key, item);
  rb_fix_chld (y, lm, d);

  // Rebalance the tree
  while (IS_RED (lm->parent))
    {
      d = rb_which_chld (lm->parent);
      dd = D_OPPOSITE (d);

      y = rb_child (lm->parent->parent, dd, curts);
      if (IS_RED (y))
	{
	  SET_BLACK (lm->parent);
	  SET_BLACK (y);
	  SET_RED (lm->parent->parent);
	  lm = lm->parent->parent;
	}
      else
	{
	  if (rb_which_chld (lm) == dd)
	    {
	      lm = lm->parent;
	      lm = rb_rotate (lm, d);
	    }
	  SET_BLACK (lm->parent);
	  SET_RED (lm->parent->parent);
	  rb_rotate (lm->parent->parent, dd);
	}
    }

  // Color the root Black
  SET_BLACK (root);
  return true;
}

bool
PRBTree::remove (Key_t key, Time_t ts)
{
  LMap *lm, *x, *y, *prnt;
  if (ts > curts)
    curts = ts;
  else if (ts < curts)
    return false; // can only update the current tree

  lm = rb_locate (key, curts, true);
  if (lm == NULL || lm->key != key)
    return false;

  if (rb_child (lm, Left, curts) && rb_child (lm, Right, curts))
    y = rb_neighbor (lm, curts);
  else
    y = lm;

  x = rb_child (y, Left, curts);
  if (x == NULL)
    x = rb_child (y, Right, curts);

  if (y != lm)
    {
      lm = rb_copy_node (lm, None); // copied with children
      lm->key = y->key;
      lm->item = y->item;
    }

  Direction d = rb_which_chld (y);
  prnt = rb_fix_chld (y->parent, x, d);
  if (IS_BLACK (y))
    rb_remove_fixup (x, prnt, d);
  return true;
}

void *
PRBTree::locate (Key_t key, Time_t ts)
{
  LMap *lm = rb_locate (key, ts, true);
  return lm ? lm->item : NULL;
}

void *
PRBTree::locate_up (Key_t key, Time_t ts)
{
  LMap *lm = rb_locate (key, ts, false);
  return lm ? lm->item : NULL;
}

void *
PRBTree::locate_exact_match (Key_t key, Time_t ts)
{
  LMap *lm = rb_locate (key, ts, true);
  if (lm && key == lm->key)
    return lm->item;
  return NULL;
}
