001: package com.quadcap.sql.file;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.File;
042: import java.io.IOException;
043:
044: import java.util.ArrayList;
045: import java.util.List;
046: import java.util.Properties;
047:
048: import com.quadcap.util.collections.LongMap;
049:
050: import com.quadcap.sql.lock.Transaction;
051:
052: import com.quadcap.util.Debug;
053:
054: /**
055: * Interface to logging subsystem.
056: *
057: * @author Stan Bailes
058: */
059: public class Log3 implements Log {
060: Datafile db;
061: Properties props;
062: LongMap tt = new LongMap(222);
063: LongMap rowMap = new LongMap(3333);
064:
065: /**
066: * Initialize the logging subsystem
067: */
068: public void init(Datafile db, boolean create, Properties props)
069: throws IOException {
070: this .db = db;
071: this .props = (Properties) props.clone();
072: }
073:
074: /**
075: * Start the logging subsystem
076: */
077: public void start() {
078: }
079:
080: /**
081: * Return the database that we're logging for
082: */
083: public Datafile getDatafile() {
084: return db;
085: }
086:
087: /**
088: * Add a transaction's log record to the end of the open log file
089: */
090: public void addEntry(LogEntry entry) throws IOException {
091: int code = entry.getCode();
092: if (code == LogEntry.BEGIN_TRANSACTION
093: || code == LogEntry.COMMIT) {
094: tt.remove(entry.getTransactionId());
095: } else if (code == LogEntry.BLOCK_WRITE) {
096: // blank
097: } else {
098: List list = (List) tt.get(entry.getTransactionId());
099: if (list == null) {
100: list = new ArrayList();
101: tt.put(entry.getTransactionId(), list);
102: }
103: list.add(entry);
104: }
105: }
106:
107: /**
108: * XXX why public?
109: */
110: public void reallyAddEntry(LogEntry entry) throws IOException {
111: addEntry(entry);
112: }
113:
114: /**
115: * Flush and close the log file.
116: */
117: public void close() throws IOException {
118: tt = new LongMap(tt.buckets());
119: }
120:
121: /**
122: * Flush all log records to disk.
123: */
124: public void flushLog() throws IOException {
125: }
126:
127: /**
128: * Perform a checkpoint operation.
129: */
130: public void checkpoint() throws IOException {
131: }
132:
133: /**
134: * Wait for all queue ops to be processed by the log sync thread
135: */
136: public void sync() throws IOException {
137: }
138:
139: /**
140: * Transaction rollback.
141: */
142: public void rollbackTransaction(Transaction trans)
143: throws IOException {
144: List list = (List) tt.get(trans.getTransactionId());
145: if (list != null) {
146: for (int i = list.size() - 1; i >= 0; i--) {
147: LogEntry entry = (LogEntry) list.get(i);
148: switch (entry.getCode()) {
149: case LogEntry.STEP:
150: if (entry.getRedoState() == LogEntry.DONE) {
151: try {
152: entry.undo(trans, db);
153: } catch (Throwable th) {
154: //#ifdef DEBUG
155: Debug
156: .println("Exception in rollback transaction");
157: Debug.print(th);
158: //#endif
159: }
160: entry.setRedoState(LogEntry.UNDONE);
161: }
162: break;
163: default:
164: break;
165: }
166: }
167: }
168: }
169:
170: /**
171: * Statement rollback.
172: */
173: public void rollbackStatement(Transaction trans, int stmtId)
174: throws IOException {
175: List list = (List) tt.get(trans.getTransactionId());
176: if (list != null) {
177: for (int i = list.size() - 1; i >= 0; i--) {
178: LogEntry entry = (LogEntry) list.get(i);
179: if (entry.getStatementId() != stmtId)
180: continue;
181:
182: switch (entry.getCode()) {
183: case LogEntry.STEP:
184: if (entry.getRedoState() == LogEntry.DONE) {
185: try {
186: entry.undo(trans, db);
187: } catch (Throwable th) {
188: //#ifdef DEBUG
189: Debug
190: .println("Exception in rollback transaction");
191: Debug.print(th);
192: //#endif
193: }
194: entry.setRedoState(LogEntry.UNDONE);
195: }
196: break;
197: case LogEntry.BEGIN_STATEMENT:
198: return;
199: default:
200: break;
201: }
202: }
203: }
204: }
205:
206: /**
207: * Restart from a previous state
208: */
209: public void restart() throws Exception {
210: }
211:
212: /**
213: * Retrieve a row mapping.
214: */
215: public long getRowMap(long rowId) {
216: long ret = rowId;
217: Long l = (Long) rowMap.get(rowId);
218: if (l != null)
219: ret = l.longValue();
220: return ret;
221: }
222:
223: /**
224: * Remember a row mapping {old,new} The old row (logRow) is now stored
225: * in a new place (fileRow), so any stored log entries that refer to
226: * the old row need to be translated to use the new row.
227: *
228: * @param logRow the "old" row
229: * @param fileRow the "new" row
230: */
231: public void putRowMap(long logRow, long fileRow) {
232: rowMap.put(logRow, new Long(fileRow));
233: }
234:
235: /**
236: * Discard a row mapping
237: */
238: public void removeRowMap(long row) {
239: rowMap.remove(row);
240: }
241:
242: /**
243: * Are you logging?
244: */
245: public boolean isLogging() {
246: return true;
247: }
248:
249: /**
250: * Save a "before" image
251: */
252: public void saveBlock(long b) throws IOException {
253: }
254:
255: /**
256: * Restore all the "before" images
257: */
258: public void restoreBlocks() throws IOException {
259: }
260:
261: /**
262: * Reset the "before" list to be empty
263: */
264: public void resetBlocks() throws IOException {
265: }
266:
267: /**
268: * Remove the log
269: */
270: public void remove() throws IOException {
271: }
272:
273: /**
274: * Are we currently performing restart log recovery?
275: */
276: public boolean inRecovery() throws IOException {
277: return false;
278: }
279: }
|