summaryrefslogtreecommitdiff
path: root/sql/sp_cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sp_cache.cc')
-rw-r--r--sql/sp_cache.cc166
1 files changed, 166 insertions, 0 deletions
diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc
new file mode 100644
index 00000000000..056ac6d7e96
--- /dev/null
+++ b/sql/sp_cache.cc
@@ -0,0 +1,166 @@
+/* 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"
+
+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, sp_name *name)
+{
+ 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->m_qname.str, name->m_qname.length);
+}
+
+bool
+sp_cache_remove(sp_cache **cp, sp_name *name)
+{
+ sp_cache *c= *cp;
+ bool found= FALSE;
+
+ 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
+ found= c->remove(name->m_qname.str, name->m_qname.length);
+ c->version= v+1;
+ }
+ return found;
+}
+
+void
+sp_cache_invalidate()
+{
+ pthread_mutex_lock(&Cversion_lock); // LOCK
+ Cversion++;
+ pthread_mutex_unlock(&Cversion_lock); // UNLOCK
+}
+
+static byte *
+hash_get_key_for_sp_head(const byte *ptr, uint *plen,
+ my_bool first)
+{
+ sp_head *sp= (sp_head *)ptr;
+
+ *plen= sp->m_qname.length;
+ return (byte*) sp->m_qname.str;
+}
+
+static void
+hash_free_sp_head(void *p)
+{
+ sp_head *sp= (sp_head *)p;
+
+ delete sp;
+}
+
+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, hash_free_sp_head, 0);
+ version= 0;
+}
+
+void
+sp_cache::cleanup()
+{
+ hash_free(&m_hashtable);
+}