001: /**
002: * com.mckoi.database.StatementCache 15 Sep 2001
003: *
004: * Mckoi SQL Database ( http://www.mckoi.com/database )
005: * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * Version 2 as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License Version 2 for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * Version 2 along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: * Change Log:
021: *
022: *
023: */package com.mckoi.database;
024:
025: import com.mckoi.util.Cache;
026: import com.mckoi.database.global.ObjectTranslator;
027: import com.mckoi.database.global.ByteLongObject;
028: import com.mckoi.debug.*;
029:
030: /**
031: * A cache that maintains a serialized set of StatementTree objects that can
032: * be deserialized on demand. The purpose of this cache is to improve the
033: * performance of queries that are run repeatedly (for example, multiple
034: * INSERT statements).
035: * <p>
036: * SYNCHRONIZATION: This object is safe to use over multiple threads.
037: *
038: * @author Tobias Downer
039: */
040:
041: public final class StatementCache {
042:
043: /**
044: * The DatabaseSystem of this cache.
045: */
046: private DatabaseSystem system;
047:
048: /**
049: * The internal cache representation.
050: */
051: private Cache cache;
052:
053: /**
054: * Constructs the cache.
055: */
056: public StatementCache(DatabaseSystem system, int hash_size,
057: int max_size, int clean_percentage) {
058: this .system = system;
059: cache = new Cache(hash_size, max_size, clean_percentage);
060: }
061:
062: /**
063: * Returns a DebugLogger object we can use to log debug messages.
064: */
065: public final DebugLogger Debug() {
066: return system.Debug();
067: }
068:
069: /**
070: * Puts a new query string/StatementTree into the cache.
071: */
072: public synchronized void put(String query_string,
073: StatementTree statement_tree) {
074: query_string = query_string.trim();
075: // Is this query string already in the cache?
076: if (cache.get(query_string) == null) {
077: try {
078: Object cloned_tree = statement_tree.clone();
079: cache.put(query_string, cloned_tree);
080: } catch (CloneNotSupportedException e) {
081: Debug().writeException(e);
082: throw new Error("Unable to clone statement tree: "
083: + e.getMessage());
084: }
085: }
086: }
087:
088: /**
089: * Gets a StatementTree for the query string if it is stored in the cache.
090: * If it isn't stored in the cache returns null.
091: */
092: public synchronized StatementTree get(String query_string) {
093: query_string = query_string.trim();
094: Object ob = cache.get(query_string);
095: if (ob != null) {
096: try {
097: // System.out.println("CACHE HIT!");
098: // We found a cached version of this query so deserialize and return
099: // it.
100: StatementTree cloned_tree = (StatementTree) ob;
101: return (StatementTree) cloned_tree.clone();
102: } catch (CloneNotSupportedException e) {
103: Debug().writeException(e);
104: throw new Error("Unable to clone statement tree: "
105: + e.getMessage());
106: }
107: }
108: // Not found so return null
109: return null;
110: }
111:
112: }
|