Commit 4f4c627b77a169e1729982fa03dd75d5035f0297

Authored by Jay Berkenbilt
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.
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");
libtests/qtest/closedfile/output
1 testing with ClosedFileInputSource 1 testing with ClosedFileInputSource
  2 +testing with ClosedFileInputSource in stay open mode
2 testing with FileInputSource 3 testing with FileInputSource
3 all assertions passed 4 all assertions passed