Compare commits
1 Commits
developmen
...
bugfix/ZEN
Author | SHA1 | Date |
---|---|---|
Jeremy Desanlis | 4663a0face |
|
@ -59,7 +59,7 @@ class Skip {
|
||||||
} else if (filteringResult === FILTER_SKIP
|
} else if (filteringResult === FILTER_SKIP
|
||||||
&& skippingRange !== SKIP_NONE) {
|
&& skippingRange !== SKIP_NONE) {
|
||||||
if (++this.streakLength >= MAX_STREAK_LENGTH) {
|
if (++this.streakLength >= MAX_STREAK_LENGTH) {
|
||||||
const newRange = this._inc(skippingRange);
|
const newRange = Skip._inc(skippingRange);
|
||||||
|
|
||||||
/* Avoid to loop on the same range again and again. */
|
/* Avoid to loop on the same range again and again. */
|
||||||
if (newRange === this.gteParams) {
|
if (newRange === this.gteParams) {
|
||||||
|
@ -73,7 +73,7 @@ class Skip {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_inc(str) {
|
static _inc(str) {
|
||||||
if (!str) {
|
if (!str) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
@ -85,4 +85,4 @@ class Skip {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = Skip;
|
module.exports = { Skip, MAX_STREAK_LENGTH };
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "arsenal",
|
"name": "arsenal",
|
||||||
"version": "8.0.2",
|
"version": "8.0.3",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const { Skip, MAX_STREAK_LENGTH } = require('../../../../lib/algos/list/skip');
|
||||||
|
const Delimiter =
|
||||||
|
require('../../../../lib/algos/list/delimiter').Delimiter;
|
||||||
|
|
||||||
|
describe('skip listing algorithm', () => {
|
||||||
|
it('should call listing end callback', done => {
|
||||||
|
const delimiter = new Delimiter({ maxKeys: 1 });
|
||||||
|
const skip = new Skip({ extension: delimiter });
|
||||||
|
|
||||||
|
skip.setListingEndCb(done);
|
||||||
|
skip.setSkipRangeCb(() => {});
|
||||||
|
|
||||||
|
/* Filter a first entry to reach MaxKeys and a second one to make the
|
||||||
|
* extension filter method returns FILTER_END, triggering the listing
|
||||||
|
* end event. */
|
||||||
|
skip.filter({ key: 'key1', value: 'value' });
|
||||||
|
skip.filter({ key: 'key2', value: 'value' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call skip range callback with the new range value set to the ' +
|
||||||
|
'last entry added to result, incremented', done => {
|
||||||
|
/* A delimiter with a prefix value is used to easily skip values. */
|
||||||
|
const prefix = 'prefix';
|
||||||
|
const delimiter = new Delimiter({ prefix });
|
||||||
|
const entryAddedKey = `${prefix}key`;
|
||||||
|
|
||||||
|
/* The new range value is the last added entry incremented. */
|
||||||
|
const expectedNewRange = Skip._inc(entryAddedKey);
|
||||||
|
|
||||||
|
const skip = new Skip({ extension: delimiter });
|
||||||
|
skip.setSkipRangeCb(newRange => {
|
||||||
|
assert.strictEqual(expectedNewRange, newRange);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
skip.setListingEndCb(() => {});
|
||||||
|
|
||||||
|
/* Filter a valid entry. */
|
||||||
|
skip.filter({ key: entryAddedKey, value: 'value' });
|
||||||
|
|
||||||
|
/* Filter MAX_STREAK_LENGTH skipped entries to trigger the skip range
|
||||||
|
* mechanism. */
|
||||||
|
const entries = [];
|
||||||
|
for (let i = 0; i < MAX_STREAK_LENGTH; i++) {
|
||||||
|
entries.push({
|
||||||
|
key: `key${i}`,
|
||||||
|
value: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
entries.forEach(entry => { skip.filter(entry); });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not call skip range callback when the new range is the same ' +
|
||||||
|
'than the previous one', done => {
|
||||||
|
/* To trigger this case we filter a valid entry before to filter
|
||||||
|
* STREAK_MAX_LENGTH skipped ones, to:
|
||||||
|
* - trigger the skip range callback and get the computed new range,
|
||||||
|
* - make extension.skipping function returns a value and not
|
||||||
|
* undefined.
|
||||||
|
* Then, to copy what is done by Skip code user, instanciate a new
|
||||||
|
* Skip with the new range value used a gte parameter.
|
||||||
|
* Finally, we filter STREAK_MAX_LENGTH skipped entries to trigger the
|
||||||
|
* skip scan mechanism, but as long as no entry has been accepted this
|
||||||
|
* time, the skipping function returns the same value. The new range is
|
||||||
|
* the same than the previous one and we don't call the skip range CB
|
||||||
|
* to avoid an unfinite loop.
|
||||||
|
* */
|
||||||
|
|
||||||
|
/* A delimiter with a prefix value is used to easily skip values. */
|
||||||
|
const prefix = 'prefix';
|
||||||
|
const entryAddedKey = `${prefix}key`;
|
||||||
|
const delimiter = new Delimiter({ prefix });
|
||||||
|
let skipRangeCbFirstCall = false;
|
||||||
|
const entries = [];
|
||||||
|
|
||||||
|
function skipRangeCb(range) {
|
||||||
|
if (!skipRangeCbFirstCall) {
|
||||||
|
/* Now we have a new range, instantiate a new Skip object with
|
||||||
|
* this range as gte parameter. */
|
||||||
|
skipRangeCbFirstCall = true;
|
||||||
|
const skip2 = new Skip({ extension: delimiter, gte: range });
|
||||||
|
|
||||||
|
skip2.setListingEndCb(() => {});
|
||||||
|
skip2.setSkipRangeCb(skipRangeCb);
|
||||||
|
|
||||||
|
/* Skip 100 entries. If skip range mechanism is triggered, it
|
||||||
|
* will interrupt the following filtering loop to call the
|
||||||
|
* skipRangeCb function and reaches the next assert. */
|
||||||
|
entries.forEach(entry => { skip2.filter(entry); });
|
||||||
|
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const skip = new Skip({ extension: delimiter });
|
||||||
|
skip.setListingEndCb(() => {});
|
||||||
|
skip.setSkipRangeCb(skipRangeCb);
|
||||||
|
|
||||||
|
/* Filter a valid entry. */
|
||||||
|
skip.filter({ key: entryAddedKey, value: 'value' });
|
||||||
|
|
||||||
|
/* Filter MAX_STREAK_LENGTH entries which will be skipped. */
|
||||||
|
for (let i = 0; i < MAX_STREAK_LENGTH; i++) {
|
||||||
|
entries.push({
|
||||||
|
key: `key${i}`,
|
||||||
|
value: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
entries.forEach(entry => { skip.filter(entry); });
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue