// FEATURE: 300792 public LogRecord getNext(LogRecord lr) throws InvalidLogBufferException, LogException { if (lr == null || lr.buffer == null) throw new IllegalArgumentException(); LogBuffer buffer = lr.buffer; // get next record lr.get(buffer); if (lr.isEOB()) { long bsn = buffer.bsn; // so we can test for wraparound try { lfmgr.read(buffer, buffer.bsn + 1); } catch (IOException e) { LogFile lf = lr.buffer.lf; String msg = "Error reading " + lf.file + " @ position [" + lf.position + "]"; throw new LogException(msg, e); } if (buffer.bsn == -1 || buffer.bsn < bsn) // BUG 304982 { lr.type = LogRecordType.END_OF_LOG; return lr; } lr.get(buffer); } return lr; }
/** close the Log files and perform necessary cleanup tasks. */ public void close() throws IOException, InterruptedException { // prevent new threads from adding to the log synchronized (this) { isClosed = true; } lfmgr.close(); }
/** * sets the LogFile's mark. * * <p><i> mark() </i> provides a generalized method for callers to inform the Logger that log * space can be released for reuse. * * <p>calls LogFileManager to process the request. * * @param key is a log key returned by a previous call to put(). * @param force a boolean that indicates whether the mark data should be forced to disk. When set * to <b> true </b> the caller is blocked until the mark record is forced to disk. * @throws InvalidLogKeyException if <i> key </i> parameter is out of range. <i> key </i> must be * greater than current activeMark and less than the most recent key returned by put(). * @throws LogClosedException if this logger instance has been closed. */ public void mark(long key, boolean force) throws InvalidLogKeyException, LogClosedException, IOException, InterruptedException { synchronized (this) { if (isClosed) throw new LogClosedException("log is closed"); } lfmgr.mark(key, force); }
/** * Sets the LogFile marking mode. * * <p>passes call to LogFileManager.setAutoMark(boolean) * * @param autoMark true to indicate automatic marking. * @see LogFileManager#setAutoMark(boolean) * @see LogFileManager#activeMark */ public void setAutoMark(boolean autoMark) throws InvalidLogKeyException, LogClosedException, LogFileOverflowException, IOException, InterruptedException { synchronized (this) { if (this.isClosed) throw new LogClosedException(); } lfmgr.setAutoMark(autoMark); }
/** * open Log files and perform necessart initialization. * * <p>TODO: consider open(String name) to allow named configurations. this would allow utility to * open two loggers and copy old records to new files. */ public void open() throws InvalidFileSetException, IOException, LogConfigurationException, InvalidLogBufferException, InterruptedException { lfmgr.open(); try { bmgr.open(); } catch (ClassNotFoundException e) { String cnf = "LogBuffer Class not found: " + config.getBufferClassName(); LogConfigurationException lce = new LogConfigurationException(cnf, e); throw lce; } // read header information from each file lfmgr.init(bmgr); // indicate that Log is ready for use. synchronized (this) { isClosed = false; } }
/** * return an XML node containing statistics for the Logger, the LogFile pool and the LogBuffer * pool. * * <p>The getStats method for the LogBufferManager and LogFileManager are called to include * statistics for these contained objects. * * @return String contiining XML node. */ public String getStats() { String name = this.getClass().getName(); StringBuffer stats = new StringBuffer("<Logger class='" + name + "'>"); // TODO: append Logger specific stats stats.append(bmgr.getStats()); stats.append(lfmgr.getStats()); stats.append("\n</Logger>" + "\n"); return stats.toString(); }
/** * Sub-classes call this method to write log records with a specific record type. * * @param type a record type defined in LogRecordType. * @param data record data to be logged. * @param sync boolean indicating whether call should wait for data to be written to physical * disk. * @return a log key that can be used to reference the record. */ protected long put(short type, byte[][] data, boolean sync) throws LogClosedException, LogRecordSizeException, LogFileOverflowException, InterruptedException, IOException { synchronized (this) { if (isClosed) throw new LogClosedException(); } // QUESTION: should we deal with exceptions here? long key = bmgr.put(type, data, sync); lfmgr.setCurrentKey(key); return key; }
// FEATURE: 300792 public LogRecord get(LogRecord lr, long mark) throws InvalidLogKeyException, LogConfigurationException, LogException, InvalidLogBufferException { /* this code is similar to LogBufferManager.replay() -- potential for refactor */ int bsn = bmgr.bsnFromMark(mark); if (mark < 0 || (bsn == 0 && mark != 0)) throw new InvalidLogKeyException(Long.toHexString(mark)); if (lr == null) lr = new LogRecord((config.getBufferSize() * 1024) / 4); // default to 1/4 buffer size // allocate a LogBuffer that we can use to read the journal try { if (lr.buffer == null) lr.buffer = bmgr.getLogBuffer(-1); } catch (ClassNotFoundException e) { throw new LogConfigurationException(e); } LogBuffer buffer = lr.buffer; // read block containing requested mark try { bmgr.forceCurrentBuffer(); lfmgr.read(buffer, bsn); } catch (IOException e) { LogFile lf = buffer.lf; String msg = "Error reading " + lf.file + " @ position [" + lf.position + "]"; throw new LogException(msg, e); } if (buffer.bsn == -1) { lr.type = LogRecordType.END_OF_LOG; return lr; } // verify we have the desired block // if requested mark == 0 then we start with the oldest block available int markBSN = (mark == 0) ? buffer.bsn : bmgr.bsnFromMark(mark); if (markBSN != buffer.bsn) { InvalidLogBufferException lbe = new InvalidLogBufferException( "block read [" + buffer.bsn + "] not block requested: " + markBSN); throw lbe; } /* * position buffer to requested mark. * * Although the mark contains a buffer offset, we search forward * through the buffer to guarantee that we have the start * of a record. This protects against using marks that were * not generated by the current Logger. */ lr.get(buffer); // get first record in buffer if (mark > 0 && mark > bmgr.markFromBsn(markBSN, 0)) { while (lr.key < mark) { lr.get(buffer); } if (lr.key != mark) { String msg = "The requested mark [" + Long.toHexString(mark) + "] was not found in the log."; // BUG 300733 following line changed to throw an exception throw new InvalidLogKeyException(msg); } } return lr; }
/** * Registers a LogEventListener for log event notifications. * * @param eventListener object to be notified of logger events. */ public void setLogEventListener(LogEventListener eventListener) { lfmgr.setLogEventListener(eventListener); }