~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to plugin/memcached_query_cache/invalidator.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * Copyright (c) 2010, Djellel Eddine Difallah
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions are met:
 
7
 *
 
8
 *   * Redistributions of source code must retain the above copyright notice,
 
9
 *     this list of conditions and the following disclaimer.
 
10
 *   * Redistributions in binary form must reproduce the above copyright notice,
 
11
 *     this list of conditions and the following disclaimer in the documentation
 
12
 *     and/or other materials provided with the distribution.
 
13
 *   * Neither the name of Djellel Eddine Difallah nor the names of its contributors
 
14
 *     may be used to endorse or promote products derived from this software
 
15
 *     without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
18
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 
21
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
27
 * THE POSSIBILITY OF SUCH DAMAGE.
 
28
 */
 
29
 
 
30
#include "config.h"
 
31
#include "invalidator.h"
 
32
#include "query_cache_service.h"
 
33
#include "memcached_qc.h"
 
34
 
 
35
#include <drizzled/session.h>
 
36
#include <drizzled/message/transaction.pb.h>
 
37
#include <drizzled/message/table.pb.h>
 
38
#include <drizzled/message/statement_transform.h>
 
39
 
 
40
#include <vector>
 
41
#include <string>
 
42
#include <algorithm>
 
43
 
 
44
 
 
45
using namespace drizzled;
 
46
using namespace std;
 
47
 
 
48
Invalidator::Invalidator(string name_arg)
 
49
  : 
 
50
    plugin::TransactionApplier(name_arg)
 
51
{
 
52
}
 
53
 
 
54
plugin::ReplicationReturnCode
 
55
Invalidator::apply(Session &in_session, 
 
56
                   const message::Transaction &to_apply)
 
57
{
 
58
  (void) in_session;
 
59
  string schema_name;
 
60
  string table_name;
 
61
 
 
62
  size_t stmt_size= to_apply.statement_size();
 
63
 
 
64
  for (size_t i= 0; i < stmt_size; i++)
 
65
  {
 
66
    schema_name.clear();
 
67
    table_name.clear();
 
68
    const message::Statement &stmt= to_apply.statement(i);
 
69
 
 
70
    /*
 
71
     * We don't handle raw SQL for now.
 
72
     */
 
73
    if (stmt.type() != message::Statement::RAW_SQL)
 
74
    {
 
75
      parseStatementTableMetadata(stmt, schema_name, table_name);
 
76
    }
 
77
    else
 
78
    {
 
79
      continue; /* go on to the next statement */
 
80
    }
 
81
 
 
82
    /* Now lets invalidate all the entries of the table */
 
83
    invalidateByTableName(schema_name, table_name);
 
84
  }
 
85
 return plugin::SUCCESS;
 
86
}
 
87
 
 
88
void Invalidator::parseStatementTableMetadata(const message::Statement &in_statement,
 
89
                                                  string &in_schema_name,
 
90
                                                  string &in_table_name) const
 
91
{
 
92
  switch (in_statement.type())
 
93
  {
 
94
    case message::Statement::INSERT:
 
95
    {
 
96
      const message::TableMetadata &metadata= in_statement.insert_header().table_metadata();
 
97
      in_schema_name.assign(metadata.schema_name());
 
98
      in_table_name.assign(metadata.table_name());
 
99
      break;
 
100
    }
 
101
    case message::Statement::UPDATE:
 
102
    {
 
103
      const message::TableMetadata &metadata= in_statement.update_header().table_metadata();
 
104
      in_schema_name.assign(metadata.schema_name());
 
105
      in_table_name.assign(metadata.table_name());
 
106
      break;
 
107
    }
 
108
    case message::Statement::DELETE:
 
109
    {
 
110
      const message::TableMetadata &metadata= in_statement.delete_header().table_metadata();
 
111
      in_schema_name.assign(metadata.schema_name());
 
112
      in_table_name.assign(metadata.table_name());
 
113
      break;
 
114
    }
 
115
    case message::Statement::CREATE_SCHEMA:
 
116
    {
 
117
      in_schema_name.assign(in_statement.create_schema_statement().schema().name());
 
118
      in_table_name.clear();
 
119
      break;
 
120
    }
 
121
    case message::Statement::ALTER_SCHEMA:
 
122
    {
 
123
      in_schema_name.assign(in_statement.alter_schema_statement().after().name());
 
124
      in_table_name.clear();
 
125
      break;
 
126
    }
 
127
    case message::Statement::DROP_SCHEMA:
 
128
    {
 
129
      in_schema_name.assign(in_statement.drop_schema_statement().schema_name());
 
130
      in_table_name.clear();
 
131
      break;
 
132
    }
 
133
    case message::Statement::CREATE_TABLE:
 
134
    {
 
135
      in_schema_name.assign(in_statement.create_table_statement().table().schema());
 
136
      in_table_name.assign(in_statement.create_table_statement().table().name());
 
137
      break;
 
138
    }
 
139
    case message::Statement::ALTER_TABLE:
 
140
    {
 
141
      in_schema_name.assign(in_statement.alter_table_statement().before().schema());
 
142
      in_table_name.assign(in_statement.alter_table_statement().before().name());
 
143
      break;
 
144
    }
 
145
    case message::Statement::DROP_TABLE:
 
146
    {
 
147
      const message::TableMetadata &metadata= in_statement.drop_table_statement().table_metadata();
 
148
      in_schema_name.assign(metadata.schema_name());
 
149
      in_table_name.assign(metadata.table_name());
 
150
      break;
 
151
    }
 
152
    default:
 
153
    {
 
154
      /* All other types have no schema and table information */
 
155
      in_schema_name.clear();
 
156
      in_table_name.clear();
 
157
      break;
 
158
    }
 
159
  }  
 
160
}
 
161
void Invalidator::invalidateByTableName(const std::string &in_schema_name,
 
162
                                        const std::string &in_table_name) const
 
163
{
 
164
  /* Reconstitute the schema+table key */
 
165
  string key= in_schema_name+in_table_name;
 
166
 
 
167
  /* Lookup for the invalidated table in the cached tables map */
 
168
  QueryCacheService::CachedTablesEntries::iterator itt= QueryCacheService::cachedTables.find(key);
 
169
  if (itt != QueryCacheService::cachedTables.end())
 
170
  {
 
171
    /* Extract the invloved hashes from the map and lookup the local Cache*/
 
172
    QueryCacheService::CachedTablesEntry &entry= *itt;
 
173
    vector<string>::iterator hash;
 
174
    for(hash= entry.second.begin(); hash != entry.second.end(); hash++)
 
175
    {
 
176
      QueryCacheService::CacheEntries::iterator it= QueryCacheService::cache.find(*hash);
 
177
      if (it != QueryCacheService::cache.end())
 
178
      {
 
179
        /* Remove the Query from the local Cache */
 
180
        QueryCacheService::cache.erase(*hash);
 
181
        /* Remove the Query from Memcached immediatly */
 
182
        MemcachedQueryCache::getClient()->remove(*hash, 0);
 
183
      }
 
184
    }
 
185
    /* finaly remove the table from the cached table list */
 
186
    QueryCacheService::cachedTables.erase(key);
 
187
  } 
 
188
}