@Override public void write(byte arr[], int off, int len) throws IOException { for (; ; ) { int space = buf.length - pos; if (len <= space) { System.arraycopy(arr, off, buf, pos, len); pos += len; return; } else if (len > buf.length) { if (pos > 0) { flush(buf, 0, pos); // flush written += pos; pos = 0; } // don't buffer, just write to sink flush(arr, off, len); written += len; return; } // buffer is too big to fit in the free space, but // not big enough to warrant writing on its own. // write whatever we can fit, then flush and iterate. System.arraycopy(arr, off, buf, pos, space); written += buf.length; // important to do this first, since buf.length can change after a flush! flush(buf, 0, buf.length); pos = 0; off += space; len -= space; } }
/** Only flushes the buffer of the FastOutputStream, not that of the underlying stream. */ public void flushBuffer() throws IOException { if (pos > 0) { written += pos; flush(buf, 0, pos); pos = 0; } }
protected void close() { try { if (debug) { log.debug("Closing tlog" + this); } synchronized (this) { fos.flush(); fos.close(); } if (deleteOnClose) { try { Files.deleteIfExists(tlogFile.toPath()); } catch (IOException e) { // TODO: should this class care if a file couldnt be deleted? // this just emulates previous behavior, where only SecurityException would be handled. } } } catch (IOException e) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e); } finally { assert ObjectReleaseTracker.release(this); } }
public long writeCommit(CommitUpdateCommand cmd, int flags) { LogCodec codec = new LogCodec(resolver); synchronized (this) { try { long pos = fos.size(); // if we had flushed, this should be equal to channel.position() if (pos == 0) { writeLogHeader(codec); pos = fos.size(); } codec.init(fos); codec.writeTag(JavaBinCodec.ARR, 3); codec.writeInt(UpdateLog.COMMIT | flags); // should just take one byte codec.writeLong(cmd.getVersion()); codec.writeStr(END_MESSAGE); // ensure these bytes are (almost) last in the file endRecord(pos); fos.flush(); // flush since this will be the last record in a log fill assert fos.size() == channel.size(); return pos; } catch (IOException e) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e); } } }
public void write(byte b) throws IOException { if (pos >= buf.length) { written += pos; flush(buf, 0, buf.length); pos = 0; } buf[pos++] = b; }
// This could mess with any readers or reverse readers that are open, or anything that might try // to do a log lookup. // This should only be used to roll back buffered updates, not actually applied updates. public void rollback(long pos) throws IOException { synchronized (this) { assert snapshot_size == pos; fos.flush(); raf.setLength(pos); fos.setWritten(pos); assert fos.size() == pos; numRecords = snapshot_numRecords; } }
public boolean endsWithCommit() throws IOException { long size; synchronized (this) { fos.flush(); size = fos.size(); } // the end of the file should have the end message (added during a commit) plus a 4 byte size byte[] buf = new byte[END_MESSAGE.length()]; long pos = size - END_MESSAGE.length() - 4; if (pos < 0) return false; ChannelFastInputStream is = new ChannelFastInputStream(channel, pos); is.read(buf); for (int i = 0; i < buf.length; i++) { if (buf[i] != END_MESSAGE.charAt(i)) return false; } return true; }