Commit 4f4c627b77a169e1729982fa03dd75d5035f0297
1 parent
7855e18a
ClosedFileInputSource: add method to keep file open
During periods of intensive operation on a specific file, this method can reduce the overhead of repeated open/close operations.
Showing
5 changed files
with
41 additions
and
1 deletions
ChangeLog
| 1 | +2018-08-04 Jay Berkenbilt <ejb@ql.org> | |
| 2 | + | |
| 3 | + * Add ClosedFileInputSource::stayOpen method, enabling a | |
| 4 | + ClosedFileInputSource to stay open during manually indicated | |
| 5 | + periods of high activity, thus reducing the overhead of frequent | |
| 6 | + open/close operations. | |
| 7 | + | |
| 1 | 8 | 2018-06-23 Jay Berkenbilt <ejb@ql.org> |
| 2 | 9 | |
| 3 | 10 | * 8.1.0: release | ... | ... |
include/qpdf/ClosedFileInputSource.hh
| ... | ... | @@ -55,6 +55,13 @@ class ClosedFileInputSource: public InputSource |
| 55 | 55 | QPDF_DLL |
| 56 | 56 | virtual void unreadCh(char ch); |
| 57 | 57 | |
| 58 | + // The file stays open between calls to stayOpen(true) and | |
| 59 | + // stayOpen(false). You can use this to surround multiple | |
| 60 | + // operations on a single ClosedFileInputSource to reduce the | |
| 61 | + // overhead of a separate open/close on each call. | |
| 62 | + QPDF_DLL | |
| 63 | + void stayOpen(bool); | |
| 64 | + | |
| 58 | 65 | private: |
| 59 | 66 | ClosedFileInputSource(ClosedFileInputSource const&); |
| 60 | 67 | ClosedFileInputSource& operator=(ClosedFileInputSource const&); |
| ... | ... | @@ -76,6 +83,7 @@ class ClosedFileInputSource: public InputSource |
| 76 | 83 | std::string filename; |
| 77 | 84 | qpdf_offset_t offset; |
| 78 | 85 | FileInputSource* fis; |
| 86 | + bool stay_open; | |
| 79 | 87 | }; |
| 80 | 88 | PointerHolder<Members> m; |
| 81 | 89 | }; | ... | ... |
libqpdf/ClosedFileInputSource.cc
| ... | ... | @@ -4,7 +4,8 @@ |
| 4 | 4 | ClosedFileInputSource::Members::Members(char const* filename) : |
| 5 | 5 | filename(filename), |
| 6 | 6 | offset(0), |
| 7 | - fis(0) | |
| 7 | + fis(0), | |
| 8 | + stay_open(false) | |
| 8 | 9 | { |
| 9 | 10 | } |
| 10 | 11 | |
| ... | ... | @@ -42,6 +43,10 @@ ClosedFileInputSource::after() |
| 42 | 43 | { |
| 43 | 44 | this->last_offset = this->m->fis->getLastOffset(); |
| 44 | 45 | this->m->offset = this->m->fis->tell(); |
| 46 | + if (this->m->stay_open) | |
| 47 | + { | |
| 48 | + return; | |
| 49 | + } | |
| 45 | 50 | delete this->m->fis; |
| 46 | 51 | this->m->fis = 0; |
| 47 | 52 | } |
| ... | ... | @@ -82,6 +87,10 @@ void |
| 82 | 87 | ClosedFileInputSource::rewind() |
| 83 | 88 | { |
| 84 | 89 | this->m->offset = 0; |
| 90 | + if (this->m->fis) | |
| 91 | + { | |
| 92 | + this->m->fis->rewind(); | |
| 93 | + } | |
| 85 | 94 | } |
| 86 | 95 | |
| 87 | 96 | size_t |
| ... | ... | @@ -101,3 +110,13 @@ ClosedFileInputSource::unreadCh(char ch) |
| 101 | 110 | // Don't call after -- the file has to stay open after this |
| 102 | 111 | // operation. |
| 103 | 112 | } |
| 113 | + | |
| 114 | +void | |
| 115 | +ClosedFileInputSource::stayOpen(bool val) | |
| 116 | +{ | |
| 117 | + this->m->stay_open = val; | |
| 118 | + if ((! val) && this->m->fis) | |
| 119 | + { | |
| 120 | + after(); | |
| 121 | + } | |
| 122 | +} | ... | ... |
libtests/closed_file_input_source.cc
| ... | ... | @@ -65,6 +65,11 @@ int main() |
| 65 | 65 | std::cout << "testing with ClosedFileInputSource\n"; |
| 66 | 66 | ClosedFileInputSource cf("input"); |
| 67 | 67 | do_tests(&cf); |
| 68 | + std::cout << "testing with ClosedFileInputSource in stay open mode\n"; | |
| 69 | + ClosedFileInputSource cf2("input"); | |
| 70 | + cf2.stayOpen(true); | |
| 71 | + do_tests(&cf2); | |
| 72 | + cf2.stayOpen(false); | |
| 68 | 73 | std::cout << "testing with FileInputSource\n"; |
| 69 | 74 | FileInputSource f; |
| 70 | 75 | f.setFilename("input"); | ... | ... |