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 | 2018-06-23 Jay Berkenbilt <ejb@ql.org> | 8 | 2018-06-23 Jay Berkenbilt <ejb@ql.org> |
| 2 | 9 | ||
| 3 | * 8.1.0: release | 10 | * 8.1.0: release |
include/qpdf/ClosedFileInputSource.hh
| @@ -55,6 +55,13 @@ class ClosedFileInputSource: public InputSource | @@ -55,6 +55,13 @@ class ClosedFileInputSource: public InputSource | ||
| 55 | QPDF_DLL | 55 | QPDF_DLL |
| 56 | virtual void unreadCh(char ch); | 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 | private: | 65 | private: |
| 59 | ClosedFileInputSource(ClosedFileInputSource const&); | 66 | ClosedFileInputSource(ClosedFileInputSource const&); |
| 60 | ClosedFileInputSource& operator=(ClosedFileInputSource const&); | 67 | ClosedFileInputSource& operator=(ClosedFileInputSource const&); |
| @@ -76,6 +83,7 @@ class ClosedFileInputSource: public InputSource | @@ -76,6 +83,7 @@ class ClosedFileInputSource: public InputSource | ||
| 76 | std::string filename; | 83 | std::string filename; |
| 77 | qpdf_offset_t offset; | 84 | qpdf_offset_t offset; |
| 78 | FileInputSource* fis; | 85 | FileInputSource* fis; |
| 86 | + bool stay_open; | ||
| 79 | }; | 87 | }; |
| 80 | PointerHolder<Members> m; | 88 | PointerHolder<Members> m; |
| 81 | }; | 89 | }; |
libqpdf/ClosedFileInputSource.cc
| @@ -4,7 +4,8 @@ | @@ -4,7 +4,8 @@ | ||
| 4 | ClosedFileInputSource::Members::Members(char const* filename) : | 4 | ClosedFileInputSource::Members::Members(char const* filename) : |
| 5 | filename(filename), | 5 | filename(filename), |
| 6 | offset(0), | 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,6 +43,10 @@ ClosedFileInputSource::after() | ||
| 42 | { | 43 | { |
| 43 | this->last_offset = this->m->fis->getLastOffset(); | 44 | this->last_offset = this->m->fis->getLastOffset(); |
| 44 | this->m->offset = this->m->fis->tell(); | 45 | this->m->offset = this->m->fis->tell(); |
| 46 | + if (this->m->stay_open) | ||
| 47 | + { | ||
| 48 | + return; | ||
| 49 | + } | ||
| 45 | delete this->m->fis; | 50 | delete this->m->fis; |
| 46 | this->m->fis = 0; | 51 | this->m->fis = 0; |
| 47 | } | 52 | } |
| @@ -82,6 +87,10 @@ void | @@ -82,6 +87,10 @@ void | ||
| 82 | ClosedFileInputSource::rewind() | 87 | ClosedFileInputSource::rewind() |
| 83 | { | 88 | { |
| 84 | this->m->offset = 0; | 89 | this->m->offset = 0; |
| 90 | + if (this->m->fis) | ||
| 91 | + { | ||
| 92 | + this->m->fis->rewind(); | ||
| 93 | + } | ||
| 85 | } | 94 | } |
| 86 | 95 | ||
| 87 | size_t | 96 | size_t |
| @@ -101,3 +110,13 @@ ClosedFileInputSource::unreadCh(char ch) | @@ -101,3 +110,13 @@ ClosedFileInputSource::unreadCh(char ch) | ||
| 101 | // Don't call after -- the file has to stay open after this | 110 | // Don't call after -- the file has to stay open after this |
| 102 | // operation. | 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,6 +65,11 @@ int main() | ||
| 65 | std::cout << "testing with ClosedFileInputSource\n"; | 65 | std::cout << "testing with ClosedFileInputSource\n"; |
| 66 | ClosedFileInputSource cf("input"); | 66 | ClosedFileInputSource cf("input"); |
| 67 | do_tests(&cf); | 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 | std::cout << "testing with FileInputSource\n"; | 73 | std::cout << "testing with FileInputSource\n"; |
| 69 | FileInputSource f; | 74 | FileInputSource f; |
| 70 | f.setFilename("input"); | 75 | f.setFilename("input"); |