sp_cache.cc 2.63 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/* Copyright (C) 2002 MySQL AB

   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 2 of the License, 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifdef __GNUC__
#pragma implementation
#endif

#include "mysql_priv.h"
#include "sp_cache.h"
#include "sp_head.h"

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
static pthread_mutex_t Cversion_lock;
static ulong Cversion = 0;

void
sp_cache_init()
{
  pthread_mutex_init(&Cversion_lock, MY_MUTEX_INIT_FAST);
}

void
sp_cache_clear(sp_cache **cp)
{
  sp_cache *c= *cp;

  if (c)
  {
    delete c;
    *cp= NULL;
  }
}

void
sp_cache_insert(sp_cache **cp, sp_head *sp)
{
  sp_cache *c= *cp;

  if (! c)
    c= new sp_cache();
  if (c)
  {
    ulong v;

    pthread_mutex_lock(&Cversion_lock); // LOCK
    v= Cversion;
    pthread_mutex_unlock(&Cversion_lock); // UNLOCK

    if (c->version < v)
    {
      if (*cp)
	c->remove_all();
      c->version= v;
    }
    c->insert(sp);
    if (*cp == NULL)
      *cp= c;
  }
}

sp_head *
sp_cache_lookup(sp_cache **cp, char *name, uint namelen)
{
  ulong v;
  sp_cache *c= *cp;

  if (! c)
    return NULL;

  pthread_mutex_lock(&Cversion_lock); // LOCK
  v= Cversion;
  pthread_mutex_unlock(&Cversion_lock); // UNLOCK

  if (c->version < v)
  {
    c->remove_all();
    c->version= v;
    return NULL;
  }
  return c->lookup(name, namelen);
}

unknown's avatar
unknown committed
95 96
sp_head *
sp_cache_remove(sp_cache **cp, char *name, uint namelen)
97 98
{
  sp_cache *c= *cp;
unknown's avatar
unknown committed
99
  sp_head *sp= NULL;
100 101 102 103 104 105 106 107 108 109 110 111

  if (c)
  {
    ulong v;

    pthread_mutex_lock(&Cversion_lock); // LOCK
    v= Cversion++;
    pthread_mutex_unlock(&Cversion_lock); // UNLOCK

    if (c->version < v)
      c->remove_all();
    else
unknown's avatar
unknown committed
112
      sp= c->remove(name, namelen);
113 114
    c->version= v+1;
  }
unknown's avatar
unknown committed
115
  return sp;
116 117 118
}


119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
static byte *
hash_get_key_for_sp_head(const byte *ptr, uint *plen,
			       my_bool first)
{
  return ((sp_head*)ptr)->name(plen);
}

sp_cache::sp_cache()
{
  init();
}

sp_cache::~sp_cache()
{
  hash_free(&m_hashtable);
}

void
sp_cache::init()
{
  hash_init(&m_hashtable, system_charset_info, 0, 0, 0,
	    hash_get_key_for_sp_head, 0, 0);
141
  version= 0;
142 143 144 145 146 147 148
}

void
sp_cache::cleanup()
{
  hash_free(&m_hashtable);
}