diff --git a/java/org/jlab/coda/hipo/Writer.java b/java/org/jlab/coda/hipo/Writer.java index 006acc83..9c452f77 100644 --- a/java/org/jlab/coda/hipo/Writer.java +++ b/java/org/jlab/coda/hipo/Writer.java @@ -122,9 +122,7 @@ public class Writer implements AutoCloseable { * No file is opened. Any file will have little endian byte order. */ public Writer() { - outputRecord = new RecordOutputStream(); - fileHeader = new FileHeader(true); - headerBuffer.order(byteOrder); + this(HeaderType.EVIO_FILE, ByteOrder.LITTLE_ENDIAN, 0, 0); } /** @@ -422,6 +420,35 @@ public void addTrailerWithIndex(boolean addTrailingIndex) { } } + /** Called by open(), needed if open called multiple times in succession. */ + private void clear() { + // If writing to file ... + if (toFile) { + future1 = null; + future2 = null; + futureIndex = 0; + fileWritingPosition = 0L; + + internalRecords[0].reset(); + internalRecords[1].reset(); + internalRecords[2].reset(); + outputRecord = internalRecords[0]; + + usedRecords[0] = null; + usedRecords[1] = null; + } + + // For both files & buffers + outputRecord.reset(); + headerBuffer.clear(); + recordLengths.clear(); + writerBytesWritten = 0; + recordNumber = 1; + closed = false; + opened = false; + firstRecordWritten = false; + } + /** * Open a new file and write file header with no user header. * Will not overwrite existing file. @@ -482,6 +509,8 @@ else if (!toFile) { throw new HipoException("filename arg is null"); } + clear(); + ByteBuffer headBuffer; haveUserHeader = false; @@ -573,6 +602,8 @@ else if (toFile) { throw new HipoException("bad arg"); } + clear(); + if (userHdr == null) { if (dictionaryFirstEventBuffer != null) { userHeader = dictionaryFirstEventBuffer.array(); @@ -1215,21 +1246,6 @@ private void writeOutputToBuffer() { //--------------------------------------------------------------------- - /** Get this object ready for re-use. - * Follow calling this with call to {@link #open(String)}. */ - public void reset() { - outputRecord.reset(); - fileHeader.reset(); - writerBytesWritten = 0L; - recordNumber = 1; - addTrailer = false; - firstRecordWritten = false; - - closed = false; - opened = false; - } - - /** * Close opened file. If the output record contains events, * they will be flushed to file/buffer. Trailer and its optional index diff --git a/java/org/jlab/coda/hipo/WriterMT.java b/java/org/jlab/coda/hipo/WriterMT.java index b9966409..2054a8f6 100644 --- a/java/org/jlab/coda/hipo/WriterMT.java +++ b/java/org/jlab/coda/hipo/WriterMT.java @@ -113,8 +113,6 @@ public class WriterMT implements AutoCloseable { private boolean closed; /** Has open() been called? */ private boolean opened; - /** Has the first record been written already? */ - private boolean firstRecordWritten; /** Has a dictionary been defined? */ private boolean haveDictionary; /** Has a first event been defined? */ @@ -547,6 +545,20 @@ public void addTrailerWithIndex(boolean addTrailingIndex) { } } + /** Called by open(), needed if open called multiple times in succession. */ + private void clear() { + // outputRecord belongs to ringItem which is taken from supply and is put back in close() + if (outputRecord == null || ringItem == null) { + ringItem = supply.get(); + outputRecord = ringItem.getRecord(); + } + + writerBytesWritten = 0L; + recordNumber = 1; + closed = false; + opened = false; + } + /** * Open a new file and write file header with no user header. * Existing file is NOT overwritten. @@ -592,6 +604,8 @@ public final void open(String filename, byte[] userHdr, boolean overwrite) throw throw new HipoException("bad filename"); } + clear(); + ByteBuffer fileHeaderBuffer; haveUserHeader = false; @@ -1048,16 +1062,6 @@ public void addEvent(EvioNode node) throws HipoException { //--------------------------------------------------------------------- - /** Get this object ready for re-use. - * Follow calling this with call to {@link #open(String)}. */ - public void reset() { - outputRecord.reset(); - fileHeader.reset(); - writerBytesWritten = 0L; - recordNumber = 1; - addingTrailer = false; - } - /** * Close opened file. If the output record contains events, * they will be flushed to file. Trailer and its optional index @@ -1072,6 +1076,9 @@ public void close() { supply.publish(ringItem); } + outputRecord = null; + ringItem = null; + // Since the writer thread is the last to process each record, // wait until it's done with the last item, then exit the thread. recordWriterThread.waitForLastItem(); diff --git a/src/libsrc++/Writer.cpp b/src/libsrc++/Writer.cpp index 2ac91255..7f31c35e 100644 --- a/src/libsrc++/Writer.cpp +++ b/src/libsrc++/Writer.cpp @@ -183,7 +183,7 @@ namespace evio { dictionaryFirstEventBuffer = createDictionaryRecord(); //std::cout << "Writer const: created dict/fe event buffer of size " << dictionaryFirstEventBuffer->remaining() << std::endl; //Util::printBytes(dictionaryFirstEventBuffer, 0, dictionaryFirstEventBuffer->remaining(), "FIRST RECORD Bytes"); - // make this the user header by default since open() may not get called for buffers + // make this the user header by default // TODO: SHOULD NOT AVOID the shared pointer!!!!! Look at userHeader uses!!! userHeader = dictionaryFirstEventBuffer->array(); userHeaderLength = dictionaryFirstEventBuffer->remaining(); @@ -439,6 +439,27 @@ namespace evio { } + /** + * Called by open(), needed if open called multiple times in succession. + */ + void Writer::clear() { + + // For both files & buffers + unusedRecord->reset(); + outputRecord->reset(); + beingWrittenRecord = nullptr; + + recordLengths->clear(); + writerBytesWritten = 0; + recordNumber = 1; + closed = false; + opened = false; + firstRecordWritten = false; + + headerArray.clear(); + } + + /** * Open a new file and write file header with no user header. * @param filename output file name @@ -480,6 +501,8 @@ namespace evio { throw EvioException("bad filename"); } + clear(); + std::shared_ptr fileHeaderBuffer; haveUserHeader = false; @@ -556,6 +579,8 @@ namespace evio { throw EvioException("can only write to a file, call open(filename, userHdr)"); } + clear(); + if (userHdr == nullptr) { if (dictionaryFirstEventBuffer->remaining() > 0) { userHeader = dictionaryFirstEventBuffer->array(); @@ -698,6 +723,7 @@ namespace evio { int userHeaderBytes = 0; if (userHdr != nullptr) { userHeaderBytes = userLen; + + } // TODO: make sure next line is necessary (taken from WriterMT) fileHeader.reset(); @@ -1233,21 +1259,6 @@ namespace evio { //--------------------------------------------------------------------- - /** Get this object ready for re-use. - * Follow calling this with call to {@link #open(const std::string &)}. */ - void Writer::reset() { - outputRecord->reset(); - fileHeader.reset(); - writerBytesWritten = 0L; - recordNumber = 1; - addingTrailer = false; - firstRecordWritten = false; - - closed = false; - opened = false; - } - - /** * Close opened file. If the output record contains events, * they will be flushed to file/buffer. Trailer and its optional index diff --git a/src/libsrc++/Writer.h b/src/libsrc++/Writer.h index ebf6b1fe..f78d977c 100644 --- a/src/libsrc++/Writer.h +++ b/src/libsrc++/Writer.h @@ -221,6 +221,7 @@ namespace evio { private: + void clear(); void writeTrailer(bool writeIndex, uint32_t recordNum, uint64_t trailerPos); }; diff --git a/src/libsrc++/WriterMT.cpp b/src/libsrc++/WriterMT.cpp index 062e2011..3c088cb7 100644 --- a/src/libsrc++/WriterMT.cpp +++ b/src/libsrc++/WriterMT.cpp @@ -248,6 +248,21 @@ namespace evio { } + /** Called by open(), needed if open called multiple times in succession. */ + void WriterMT::clear() { + // outputRecord belongs to ringItem which is taken from supply and is put back in close() + if (outputRecord == nullptr || ringItem == nullptr) { + ringItem = supply->get(); + outputRecord = ringItem->getRecord(); + } + + writerBytesWritten = 0L; + recordNumber = 1; + closed = false; + opened = false; + } + + /** * Open a new file and write file header with no user header. * @param filename output file name @@ -285,6 +300,8 @@ namespace evio { throw EvioException("bad filename"); } + clear(); + std::shared_ptr fileHeaderBuffer; haveUserHeader = false; @@ -671,21 +688,6 @@ namespace evio { //--------------------------------------------------------------------- - /** Get this object ready for re-use. - * Follow calling this with call to {@link #open(const std::string &)}. */ - void WriterMT::reset() { - outputRecord->reset(); - fileHeader.reset(); - writerBytesWritten = 0L; - recordNumber = 1; - addingTrailer = false; - firstRecordWritten = false; - - closed = false; - opened = false; - } - - /** * Close opened file. If the output record contains events, * they will be flushed to file. Trailer and its optional index @@ -701,6 +703,9 @@ namespace evio { supply->publish(ringItem); } + outputRecord = nullptr; + ringItem = nullptr; + // Since the writer thread is the last to process each record, // wait until it's done with the last item, then exit the thread. recordWriterThreads[0].waitForLastItem(); diff --git a/src/libsrc++/WriterMT.h b/src/libsrc++/WriterMT.h index 2d1081f7..48522f14 100644 --- a/src/libsrc++/WriterMT.h +++ b/src/libsrc++/WriterMT.h @@ -306,8 +306,6 @@ namespace evio { bool closed = false; /** Has open() been called? */ bool opened = false; - /** Has the first record been written already? */ - bool firstRecordWritten = false; /** Has a dictionary been defined? */ bool haveDictionary = false; /** Has a first event been defined? */ @@ -349,6 +347,7 @@ namespace evio { std::shared_ptr createDictionaryRecord(); void writeTrailer(bool writeIndex, uint32_t recordNum); + void clear(); public: @@ -379,7 +378,7 @@ namespace evio { // void addEvent(EvioBank & bank); void addEvent(EvioNode & node); - void reset(); + // void reset(); void close(); };