mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Expose control of the number of open files in libvips' cache.
Breaks API of existing cache method. Disable libvips cache for I/O tests.
This commit is contained in:
parent
8843211e12
commit
11329d5e09
@ -5,6 +5,7 @@
|
||||
"maxcomplexity": 13,
|
||||
"globals": {
|
||||
"before": true,
|
||||
"after": true,
|
||||
"describe": true,
|
||||
"it": true
|
||||
}
|
||||
|
@ -41,8 +41,8 @@ Any change that modifies the existing public API should be added to the relevant
|
||||
|
||||
| Release | WIP branch |
|
||||
| ------: | :--------- |
|
||||
| v0.12.0 | look |
|
||||
| v0.13.0 | mind |
|
||||
| v0.14.0 | needle |
|
||||
|
||||
Please squash your changes into a single commit using a command like `git rebase -i upstream/<wip-branch>`.
|
||||
|
||||
|
21
docs/api.md
21
docs/api.md
@ -590,19 +590,26 @@ An Object containing the version numbers of libvips and, on Linux, its dependenc
|
||||
|
||||
### Utilities
|
||||
|
||||
#### sharp.cache([memory], [items])
|
||||
#### sharp.cache([options])
|
||||
|
||||
If `memory` or `items` are provided, set the limits of _libvips'_ operation cache.
|
||||
If `options` is provided, sets the limits of _libvips'_ operation cache.
|
||||
|
||||
* `memory` is the maximum memory in MB to use for this cache, with a default value of 100
|
||||
* `items` is the maximum number of operations to cache, with a default value of 500
|
||||
* `options.memory` is the maximum memory in MB to use for this cache, with a default value of 50
|
||||
* `options.files` is the maximum number of files to hold open, with a default value of 20
|
||||
* `options.items` is the maximum number of operations to cache, with a default value of 100
|
||||
|
||||
`options` can also be a boolean, where `true` enables the default cache settings and `false` disables all caching.
|
||||
|
||||
This method always returns cache statistics, useful for determining how much working memory is required for a particular task.
|
||||
|
||||
```javascript
|
||||
var stats = sharp.cache(); // { current: 75, high: 99, memory: 100, items: 500 }
|
||||
sharp.cache(200); // { current: 75, high: 99, memory: 200, items: 500 }
|
||||
sharp.cache(50, 200); // { current: 49, high: 99, memory: 50, items: 200}
|
||||
var stats = sharp.cache();
|
||||
```
|
||||
|
||||
```javascript
|
||||
sharp.cache( { items: 200 } );
|
||||
sharp.cache( { files: 0 } );
|
||||
sharp.cache(false);
|
||||
```
|
||||
|
||||
#### sharp.concurrency([threads])
|
||||
|
@ -1,5 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
### v0.13 - "*mind*"
|
||||
|
||||
* Control number of open files in libvips' cache; breaks existing `cache` behaviour.
|
||||
[#315](https://github.com/lovell/sharp/issues/315)
|
||||
|
||||
### v0.12 - "*look*"
|
||||
|
||||
#### v0.12.2 - 16<sup>th</sup> January 2016
|
||||
|
25
index.js
25
index.js
@ -834,18 +834,25 @@ Sharp.prototype.clone = function() {
|
||||
return clone;
|
||||
};
|
||||
|
||||
/*
|
||||
Get and set cache memory and item limits
|
||||
/**
|
||||
Get and set cache memory, file and item limits
|
||||
*/
|
||||
module.exports.cache = function(memory, items) {
|
||||
if (typeof memory !== 'number' || Number.isNaN(memory)) {
|
||||
memory = null;
|
||||
module.exports.cache = function(options) {
|
||||
if (typeof options === 'boolean') {
|
||||
if (options) {
|
||||
// Default cache settings of 50MB, 20 files, 100 items
|
||||
return sharp.cache(50, 20, 100);
|
||||
} else {
|
||||
return sharp.cache(0, 0, 0);
|
||||
}
|
||||
} else if (typeof options === 'object') {
|
||||
return sharp.cache(options.memory, options.files, options.items);
|
||||
} else {
|
||||
return sharp.cache();
|
||||
}
|
||||
if (typeof items !== 'number' || Number.isNaN(items)) {
|
||||
items = null;
|
||||
}
|
||||
return sharp.cache(memory, items);
|
||||
};
|
||||
// Ensure default cache settings are set
|
||||
module.exports.cache(true);
|
||||
|
||||
/*
|
||||
Get and set size of thread pool
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sharp",
|
||||
"version": "0.12.2",
|
||||
"version": "0.13.0",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"contributors": [
|
||||
"Pierre Inglebert <pierre.inglebert@gmail.com>",
|
||||
|
@ -11,10 +11,6 @@
|
||||
NAN_MODULE_INIT(init) {
|
||||
vips_init("sharp");
|
||||
|
||||
// Set libvips operation cache limits
|
||||
vips_cache_set_max_mem(100 * 1024 * 1024); // 100 MB
|
||||
vips_cache_set_max(500); // 500 operations
|
||||
|
||||
// Methods available to JavaScript
|
||||
Nan::Set(target, Nan::New("metadata").ToLocalChecked(),
|
||||
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(metadata)).ToLocalChecked());
|
||||
|
@ -24,33 +24,49 @@ using Nan::To;
|
||||
using Nan::Utf8String;
|
||||
|
||||
/*
|
||||
Get and set cache memory and item limits
|
||||
Get and set cache limits
|
||||
*/
|
||||
NAN_METHOD(cache) {
|
||||
HandleScope();
|
||||
|
||||
// Set cache memory limit
|
||||
// Set memory limit
|
||||
if (info[0]->IsInt32()) {
|
||||
vips_cache_set_max_mem(To<int32_t>(info[0]).FromJust() * 1048576);
|
||||
}
|
||||
|
||||
// Set cache items limit
|
||||
// Set file limit
|
||||
if (info[1]->IsInt32()) {
|
||||
vips_cache_set_max(To<int32_t>(info[1]).FromJust());
|
||||
vips_cache_set_max_files(To<int32_t>(info[1]).FromJust());
|
||||
}
|
||||
// Set items limit
|
||||
if (info[2]->IsInt32()) {
|
||||
vips_cache_set_max(To<int32_t>(info[2]).FromJust());
|
||||
}
|
||||
|
||||
// Get cache statistics
|
||||
Local<Object> cache = New<Object>();
|
||||
Set(cache, New("current").ToLocalChecked(),
|
||||
// Get memory stats
|
||||
Local<Object> memory = New<Object>();
|
||||
Set(memory, New("current").ToLocalChecked(),
|
||||
New<Integer>(static_cast<int>(round(vips_tracked_get_mem() / 1048576)))
|
||||
);
|
||||
Set(cache, New("high").ToLocalChecked(),
|
||||
Set(memory, New("high").ToLocalChecked(),
|
||||
New<Integer>(static_cast<int>(round(vips_tracked_get_mem_highwater() / 1048576)))
|
||||
);
|
||||
Set(cache, New("memory").ToLocalChecked(),
|
||||
Set(memory, New("max").ToLocalChecked(),
|
||||
New<Integer>(static_cast<int>(round(vips_cache_get_max_mem() / 1048576)))
|
||||
);
|
||||
Set(cache, New("items").ToLocalChecked(), New<Integer>(vips_cache_get_max()));
|
||||
// Get file stats
|
||||
Local<Object> files = New<Object>();
|
||||
Set(files, New("current").ToLocalChecked(), New<Integer>(vips_tracked_get_files()));
|
||||
Set(files, New("max").ToLocalChecked(), New<Integer>(vips_cache_get_max_files()));
|
||||
|
||||
// Get item stats
|
||||
Local<Object> items = New<Object>();
|
||||
Set(items, New("current").ToLocalChecked(), New<Integer>(vips_cache_get_size()));
|
||||
Set(items, New("max").ToLocalChecked(), New<Integer>(vips_cache_get_max()));
|
||||
|
||||
Local<Object> cache = New<Object>();
|
||||
Set(cache, New("memory").ToLocalChecked(), memory);
|
||||
Set(cache, New("files").ToLocalChecked(), files);
|
||||
Set(cache, New("items").ToLocalChecked(), items);
|
||||
info.GetReturnValue().Set(cache);
|
||||
}
|
||||
|
||||
@ -262,6 +278,7 @@ NAN_METHOD(_maxColourDistance) {
|
||||
vips_object_local(hook, imagePremultipliedNoAlpha2);
|
||||
image2 = imagePremultipliedNoAlpha2;
|
||||
}
|
||||
|
||||
// Calculate colour distance
|
||||
VipsImage *difference;
|
||||
if (vips_dE00(image1, image2, &difference, nullptr)) {
|
||||
@ -276,5 +293,10 @@ NAN_METHOD(_maxColourDistance) {
|
||||
return ThrowError(vips_error_buffer());
|
||||
}
|
||||
g_object_unref(hook);
|
||||
|
||||
// Clean up libvips' per-request data and threads
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
||||
info.GetReturnValue().Set(New<Number>(maxColourDistance));
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ var magickFilterBilinear = 'Triangle';
|
||||
var magickFilterBicubic = 'Lanczos';
|
||||
|
||||
// Disable libvips cache to ensure tests are as fair as they can be
|
||||
sharp.cache(0);
|
||||
sharp.cache(false);
|
||||
// Enable use of SIMD
|
||||
sharp.simd(true);
|
||||
|
||||
|
@ -4,8 +4,6 @@ var assert = require('assert');
|
||||
var fixtures = require('../fixtures');
|
||||
var sharp = require('../../index');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Alpha transparency', function() {
|
||||
|
||||
it('Flatten to black', function(done) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Blur', function() {
|
||||
|
||||
it('specific radius 1', function(done) {
|
||||
|
@ -6,9 +6,15 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Clone', function() {
|
||||
|
||||
before(function() {
|
||||
sharp.cache(false);
|
||||
});
|
||||
after(function() {
|
||||
sharp.cache(true);
|
||||
});
|
||||
|
||||
it('Read from Stream and write to multiple Streams', function(done) {
|
||||
var finishEventsExpected = 2;
|
||||
// Output stream 1
|
||||
@ -55,4 +61,5 @@ describe('Clone', function() {
|
||||
// Go
|
||||
fs.createReadStream(fixtures.inputJpg).pipe(rotator);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Colour space conversion', function() {
|
||||
|
||||
it('To greyscale', function(done) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Crop gravities', function() {
|
||||
|
||||
var testSettings = [
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Embed', function() {
|
||||
|
||||
it('JPEG within PNG, no alpha channel', function(done) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Partial image extraction', function() {
|
||||
describe('using the legacy extract(top,left,width,height) syntax', function () {
|
||||
it('JPEG', function(done) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Gamma correction', function() {
|
||||
|
||||
it('value of 0.0 (disabled)', function(done) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Interpolation', function() {
|
||||
|
||||
it('nearest neighbour', function(done) {
|
||||
|
@ -6,10 +6,15 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Input/output', function() {
|
||||
|
||||
before(function() {
|
||||
sharp.cache(false);
|
||||
});
|
||||
after(function() {
|
||||
sharp.cache(true);
|
||||
});
|
||||
|
||||
it('Read from File and write to Stream', function(done) {
|
||||
var writable = fs.createWriteStream(fixtures.outputJpg);
|
||||
writable.on('finish', function() {
|
||||
|
@ -8,8 +8,6 @@ var icc = require('icc');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Image metadata', function() {
|
||||
|
||||
it('JPEG', function(done) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Negate', function() {
|
||||
it('negate (jpeg)', function(done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Normalization', function () {
|
||||
|
||||
it('uses the same prototype for both spellings', function () {
|
||||
|
@ -4,8 +4,6 @@ var assert = require('assert');
|
||||
var fixtures = require('../fixtures');
|
||||
var sharp = require('../../index');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
// Helpers
|
||||
var getPaths = function(baseName, extension) {
|
||||
if (typeof extension === 'undefined') {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Resize dimensions', function() {
|
||||
|
||||
it('Exact crop', function(done) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Rotation', function() {
|
||||
|
||||
['Landscape', 'Portrait'].forEach(function(orientation) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Sharpen', function() {
|
||||
|
||||
it('specific radius 10', function(done) {
|
||||
|
@ -5,8 +5,6 @@ var assert = require('assert');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
describe('Threshold', function() {
|
||||
it('threshold 1 jpeg', function(done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
|
@ -10,8 +10,6 @@ var rimraf = require('rimraf');
|
||||
var sharp = require('../../index');
|
||||
var fixtures = require('../fixtures');
|
||||
|
||||
sharp.cache(0);
|
||||
|
||||
// Verifies all tiles in a given dz output directory are <= size
|
||||
var assertDeepZoomTiles = function(directory, expectedSize, expectedLevels, done) {
|
||||
// Get levels
|
||||
|
@ -10,20 +10,48 @@ describe('Utilities', function() {
|
||||
|
||||
describe('Cache', function() {
|
||||
it('Can be disabled', function() {
|
||||
var cache = sharp.cache(0, 0);
|
||||
assert.strictEqual(0, cache.memory);
|
||||
assert.strictEqual(0, cache.items);
|
||||
sharp.cache(false);
|
||||
var cache = sharp.cache(false);
|
||||
assert.strictEqual(cache.memory.current, 0);
|
||||
assert.strictEqual(cache.memory.max, 0);
|
||||
assert.strictEqual(typeof cache.memory.high, 'number');
|
||||
assert.strictEqual(cache.files.current, 0);
|
||||
assert.strictEqual(cache.files.max, 0);
|
||||
assert.strictEqual(cache.items.current, 0);
|
||||
assert.strictEqual(cache.items.max, 0);
|
||||
});
|
||||
it('Can be set to a maximum of 50MB and 500 items', function() {
|
||||
var cache = sharp.cache(50, 500);
|
||||
assert.strictEqual(50, cache.memory);
|
||||
assert.strictEqual(500, cache.items);
|
||||
it('Can be enabled with defaults', function() {
|
||||
var cache = sharp.cache(true);
|
||||
assert.strictEqual(cache.memory.max, 50);
|
||||
assert.strictEqual(cache.files.max, 20);
|
||||
assert.strictEqual(cache.items.max, 100);
|
||||
});
|
||||
it('Can be set to zero', function() {
|
||||
var cache = sharp.cache({
|
||||
memory: 0,
|
||||
files: 0,
|
||||
items: 0
|
||||
});
|
||||
assert.strictEqual(cache.memory.max, 0);
|
||||
assert.strictEqual(cache.files.max, 0);
|
||||
assert.strictEqual(cache.items.max, 0);
|
||||
});
|
||||
it('Can be set to a maximum of 10MB, 100 files and 1000 items', function() {
|
||||
var cache = sharp.cache({
|
||||
memory: 10,
|
||||
files: 100,
|
||||
items: 1000
|
||||
});
|
||||
assert.strictEqual(cache.memory.max, 10);
|
||||
assert.strictEqual(cache.files.max, 100);
|
||||
assert.strictEqual(cache.items.max, 1000);
|
||||
});
|
||||
it('Ignores invalid values', function() {
|
||||
sharp.cache(50, 500);
|
||||
sharp.cache(true);
|
||||
var cache = sharp.cache('spoons');
|
||||
assert.strictEqual(50, cache.memory);
|
||||
assert.strictEqual(500, cache.items);
|
||||
assert.strictEqual(cache.memory.max, 50);
|
||||
assert.strictEqual(cache.files.max, 20);
|
||||
assert.strictEqual(cache.items.max, 100);
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user