/* Copyright (C) 2021-2025 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;
}
