//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
//
// Description:
//      Implementation of cached data attribute class
//
// Author:  Jie Chen
//
// Revision History:
//   rsvcCacheDataAttr.cc,v
// Revision 1.1  1998/01/22  17:07:59  akers
// Addition of new NameServer
//
//
//
#include <rsvcCbk.h>
#include "rsvcCacheDataAttr.h"

rsvcCacheDataAttr::rsvcCacheDataAttr (char* attr, rsvcCacheData& data)
:cache_ (data), monitorList_ (100, 3)
{
#ifdef _TRACE_OBJECTS
  printf ("    Create rsvcCacheDataAttr Class Object\n");
#endif
  name_ = new char[strlen (attr) + 1];
  strcpy (name_, attr);
}

rsvcCacheDataAttr::~rsvcCacheDataAttr (void)
{
#ifdef _TRACE_OBJECTS
  printf ("    Create rsvcCacheDataAttr Class Object\n");
#endif
  delete []name_;

  removeAllCbks ();
}


void
rsvcCacheDataAttr::removeAllCbks (void)
{
  rsvcCbk* cbk = 0;

  rsvcHashIterator ite2 (monitorList_);
  for (ite2.init (); !ite2; ++ite2) {
    cbk = (rsvcCbk *)ite2 ();
    delete cbk;
  }
}

unsigned int
rsvcCacheDataAttr::hash (void)
{
  unsigned int h = 0, g;

  for (int i = 0; name_[i] != '\0'; i++){
    h = (h << 4) + name_[i];
    // assume 32 bit integer
    if (g = h & 0xf0000000){
      h ^= g >> 24;
      h ^= g;
    }
  }
  return h;
}

char* 
rsvcCacheDataAttr::attrName (void) const
{
  return name_;
}

int
rsvcCacheDataAttr::monitorOn (rsvcCbk& cbk)
{
  rsvcCbk* tcbk = new rsvcCbk (cbk);
  monitorList_.add (tcbk);
  
  return RSVC_SUCCESS;  
}

int
rsvcCacheDataAttr::monitorOff (rsvcCbk& cbk)
{
  rsvcHSlist& list = monitorList_.bucketRef (&cbk);
  rsvcHSlistIterator ite (list);
  rsvcCbk* tcbk = 0;
  int      found = 0;

  for (ite.init (); !ite; ++ite) {
    tcbk = (rsvcCbk *) ite ();
    if (rsvcCbk::sameCallback (tcbk, &cbk, 1)) {
      found = 1;
      break;
    }
  }
  if (found) {
    list.remove (tcbk);
    delete tcbk;
    return RSVC_SUCCESS;
  }
  return RSVC_NOTFOUND;
}

void
rsvcCacheDataAttr::notifyChannels (void)
{
  rsvcHashIterator ite (monitorList_);
  rsvcCbk* cbk = 0;

  for (ite.init (); !ite; ++ite) {
    cbk = (rsvcCbk *) ite ();
    cache_.notifySingleChannel (cbk);
  }
}

int
rsvcCacheDataAttr::getValue (rsvcCbk& /* cbk */)
{
  return RSVC_SUCCESS;
}

int
rsvcCacheDataAttr::monitorOff (void* ioptr)
{
  rsvcCbk* cbk = 0;
  rsvcHashIterator ite (monitorList_);

  for (ite.init (); !ite; ++ite) {
    cbk = (rsvcCbk *) ite ();
    if (cbk->userptr () == ioptr) {
      delete cbk;
      ite.removeCurrent ();
    }
  }
  return RSVC_SUCCESS;
}
  
