-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add page cache option to save memory #474
Conversation
89671d1
to
634d7ee
Compare
examples/example_067.php
Outdated
// Begin : 2022-01-25 | ||
// Last Update : 2022-01-25 | ||
// | ||
// Description : Example 066 for TCPDF class |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
examples/index.php
Outdated
@@ -85,6 +85,7 @@ | |||
<li>Text stretching and spacing (tracking/kerning): [<a href="example_063.php" title="PDF [new window]" target="_blank">PDF</a>]</li> | |||
<li>No-write page regions: [<a href="example_064.php" title="PDF [new window]" target="_blank">PDF</a>]</li> | |||
<li>PDF/A-1b (ISO 19005-1:2005) document: [<a href="example_065.php" title="PDF [new window]" target="_blank">PDF</a>]</li> | |||
<li>Using page cache to reduce memory usage: [<a href="example_066.php" title="PDF [new window]" target="_blank">PDF</a>]</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<li>Using page cache to reduce memory usage: [<a href="example_066.php" title="PDF [new window]" target="_blank">PDF</a>]</li> | |
<li>Using page cache to reduce memory usage: [<a href="example_067.php" title="PDF [new window]" target="_blank">PDF</a>]</li> |
tcpdf.php
Outdated
if ($this->pageCacheFile === false) | ||
$this->pageCacheFile = null; | ||
else | ||
self::$pageCacheRefCnts[(int)$this->pageCacheFile] = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ($this->pageCacheFile === false) | |
$this->pageCacheFile = null; | |
else | |
self::$pageCacheRefCnts[(int)$this->pageCacheFile] = 1; | |
if ($this->pageCacheFile === false) { | |
$this->pageCacheFile = null; | |
} else { | |
self::$pageCacheRefCnts[(int)$this->pageCacheFile] = 1; | |
} |
tcpdf.php
Outdated
if ($this->pageCacheFile !== null) | ||
{ | ||
self::$pageCacheRefCnts[(int)$this->pageCacheFile]--; | ||
if (self::$pageCacheRefCnts[(int)$this->pageCacheFile] == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use {
for your if blocks
Thanks for reviewing it, @williamdes! I think I got all the changes in and updated all the |
tcpdf.php
Outdated
{ | ||
self::$pageCacheRefCnts[(int)$this->pageCacheFile]--; | ||
if (self::$pageCacheRefCnts[(int)$this->pageCacheFile] == 0) { | ||
@fclose($this->pageCacheFile); // Suppress error since this might be the end of the PHP script |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A is ressource check might remove the need of silencing an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion. I ran a test and that seems like a better way to do this. I updated it.
tcpdf.php
Outdated
} | ||
} | ||
|
||
/** Handle cloning */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed, it feels a bit incomplete or non explained
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the comment. It's so that if you clone the object, you don't have two objects writing (and overwriting each other) to the same file.
tcpdf.php
Outdated
self::$pageCacheRefCnts[(int)$this->pageCacheFile] = 1; | ||
// Copy data | ||
fseek($origPageCacheFile, 0, SEEK_SET); | ||
while (($copyContent = fread($origPageCacheFile, 8192)) != false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missing {
Could you add a bit more comments on what each step does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the brace and added comments.
tcpdf.php
Outdated
@@ -7866,6 +7891,60 @@ public function _destroy($destroyall=false, $preserve_objcopy=false) { | |||
} | |||
} | |||
|
|||
/** Page cache reference counts */ | |||
protected static $pageCacheRefCnts = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protected static $pageCacheRefCnts = []; | |
protected static $pageCacheRefCnts = array(); |
Old php compatibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated this and one other place I used []
.
@@ -21201,7 +21332,9 @@ public function deletePage($page) { | |||
return false; | |||
} | |||
// delete current page | |||
unset($this->pages[$page]); | |||
if (isset($this->pages[$page])) { | |||
unset($this->pages[$page]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit too much indentation
Same below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I don't understand this comment. It seems to match the other if statements.
|
||
/** | ||
* Page cache index | ||
* @protected |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is crystal clear, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
@williamdes, I assume someone else will merge this at some point, right? I don't seem to have permission. |
Yes, when Nicolas will have some time he will probably review this :) |
Sounds good. Thank you. |
tcpdf.php
Outdated
@@ -7866,6 +7892,60 @@ public function _destroy($destroyall=false, $preserve_objcopy=false) { | |||
} | |||
} | |||
|
|||
/** Page cache reference counts */ | |||
protected static $pageCacheRefCnts = array(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be non static ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I intentionally have it static so that it can be shared when you clone it. The PR implements copy-on-write, so if you clone the PDF, it will share the cache until an edit is made.
I've been including this patch on production since 2019 and I haven't noticed any issues with it, so I feel like it's safer to leave this as-is, but if you want, I can remove the shared cache pages and make this non-static.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it could cause issues to users that do not expect things to be cached between pdfs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean people using the library? They would have to enable the page cache with usePageCacheFile(...)
and even if they do, I have the code internally handling the caching between PDFs, so I don't think it would cause issues or be something users even know about.
If you are referring to people developing the library, that's where I think it might cause confusion, but I think I can handle that by writing more detailed comments.
If the static
part is something you want to change, but still keep caching across PDFs, I could implement that with a new object for reference counting and since objects are shared by reference, it would act very similarly to the static variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that if you can implement a version with objects that would be better than a static variable. @MauricioFauth maybe you would have input on this feature and the use of statics?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added e5a3a7ce85c5c18066fcff7f87c3cf3f25fca2ad, which does it with an object instead. I'm not as confident in this change since it hasn't had years of real world testing, but it seems correct. Personally, I think this might be a little more confusing for library developers. With the static variable, I think it's more obvious that it's used to share data than this object by reference approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I hope someone with merge power can review this some time soon
The commit can be reverted if the static approach is preferred by the reviewer
…#620) Tested and confirmed working in PHP 7.4 and PHP 8.2
* README: tone down the warning about tc-lib-pdf Signed-off-by: Ruben Barkow-Kuder <github@r.z11.de> * Update README.md Co-authored-by: William Desportes <williamdes@wdes.fr> --------- Signed-off-by: Ruben Barkow-Kuder <github@r.z11.de> Co-authored-by: William Desportes <williamdes@wdes.fr>
* Fix of Deprecation warning with php 8.1 tecnickcom#614 * Update include/barcodes/qrcode.php Co-authored-by: William Desportes <williamdes@wdes.fr> --------- Co-authored-by: Robert Johnson Nallori <rnallori@evoketechnologies.com> Co-authored-by: johnson361 <johnson361@users.noreply.github.com> Co-authored-by: William Desportes <williamdes@wdes.fr>
…om#633) * Update tcpdf_fonts.php Fixes "use of "self" in callables is deprecated" warning is arising from tcpdf_fonts.php when using PHP >= 8.2 * Update tcpdf_fonts.php for PHP 5.3-8.2 compatibility PHP 8.2 "use of "self" in callables is deprecated" yet some ways of fixing this breaks for PHP 5.3. This approach works, tested PHP 5.3.29 - 8.2.0 * Update tcpdf_fonts.php Spaces added back in before arguments * Update tcpdf_fonts.php using get_called_class() Maneuvers compatibility of callables inside array_map() between PHP 5.3 and 8.2 - tested. --------- Co-authored-by: Nicola Asuni <nicolaasuni@users.noreply.github.com>
Co-authored-by: Nicola Asuni <nicolaasuni@users.noreply.github.com>
* Fix composite glyph output * Pad zeros before checksum calulation --------- Co-authored-by: Nicola Asuni <nicolaasuni@users.noreply.github.com>
* fix for tecnickcom#583 * fix fix --------- Co-authored-by: Nicola Asuni <nicolaasuni@users.noreply.github.com>
* Fix non-numeric value warning Fixes this warning on generating PDF: Warning: A non-numeric value encountered in /tcpdf/tcpdf.php on line 5473 * Better fix for non-numeric value warning Fixes this warning on generating PDF after calling `Text` with a non-numeric value for `$fstroke`: Warning: A non-numeric value encountered in /tcpdf/tcpdf.php on line 5470 * Update tcpdf.php Co-authored-by: William Desportes <williamdes@wdes.fr> --------- Co-authored-by: William Desportes <williamdes@wdes.fr> Co-authored-by: Nicola Asuni <nicolaasuni@users.noreply.github.com>
This was already fixed in tc-lib-barcode.
* Fix return type annotation * BC with tools that do not support PHPStan annotations Co-authored-by: William Desportes <williamdes@wdes.fr> --------- Co-authored-by: William Desportes <williamdes@wdes.fr> Co-authored-by: Nicola Asuni <nicolaasuni@users.noreply.github.com>
tecnickcom#598) * Typehints for get/setHeaderMargin are inconstent * Add typehints for header/footer margin properties --------- Co-authored-by: Nicola Asuni <nicolaasuni@users.noreply.github.com>
* Bump actions/checkout and add PHP 8.3 * Update the composer json tests * Remove PHP 5.3 and 5.4 from the matrix * add permission entry Restrict GitHub actions access --------- Co-authored-by: Nicola Asuni <nicolaasuni@users.noreply.github.com>
Running example_068.php with and without the cache enabled uses about 26MB without vs 17MB with the cache.
I rebased this to fix the merge conflicts with the examples. |
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #474 +/- ##
==========================================
+ Coverage 69.28% 72.96% +3.68%
==========================================
Files 128 129 +1
Lines 26961 21974 -4987
==========================================
- Hits 18679 16034 -2645
+ Misses 8282 5940 -2342
Flags with carried forward coverage won't be shown. Click here to find out more.
☔ View full report in Codecov by Sentry. |
I also updated this so it passes the unit tests, including on PHP 5.3. |
Thank you ! |
While this is a nice feature to have, I am not keen to accept new features as the tc-lib-pdf is already working and missing only (even if very important) HTML/CSS/SVG/Javascript support. |
Thanks, @nicolaasuni. That makes sense. I'm looking forward to the production release of tc-lib-pdf to see how it works with some of the large CSVs I generate. |
Running example_067.php with and without the cache enabled uses about 26MB without vs 17MB with the cache.
This adds the
usePageCacheFile
option which allow you to move page data to a temporary file when not in use.