The snippet below is what gets generated when we do a npm run dev
on svelte
app.
function make_dirty(ponent, i) {
if (ponent.$$.dirty[0] === -1) {
dirty_ponents.push(ponent);
schedule_update();
ponent.$$.dirty.fill(0);
}
ponent.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
}
Can anybody please explain what is happening with the statement below? Why is the number 31 hard-coded?
ponent.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
Thanks
The snippet below is what gets generated when we do a npm run dev
on svelte
app.
function make_dirty(ponent, i) {
if (ponent.$$.dirty[0] === -1) {
dirty_ponents.push(ponent);
schedule_update();
ponent.$$.dirty.fill(0);
}
ponent.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
}
Can anybody please explain what is happening with the statement below? Why is the number 31 hard-coded?
ponent.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
Thanks
Share edited Jan 1, 2020 at 9:16 Siddharth Pal asked Dec 31, 2019 at 7:39 Siddharth PalSiddharth Pal 1,45811 silver badges24 bronze badges 2- @RobertHarvey Thanks for the hint. But can you please elaborate more? – Siddharth Pal Commented Dec 31, 2019 at 16:32
-
2
The expression
(i / 31) | 0
amounts to a simple integer division. The expression1 << (i % 31)
yields a 1 in each bit place designated by indexi
. For example,i = 0
yields1
binary,i = 1
yields10
binary,i = 2
yields100
binary, and so on. – Robert Harvey Commented Dec 31, 2019 at 16:43
2 Answers
Reset to default 9To expand a bit on Tijmen's answer, I'll try and explain some of the rationale for this code as well as what it's actually doing.
A bitmask is a technique for storing multiple boolean options in a single integer. Say you have options A, B, C and D — you assign the values 1, 2, 4 and 8 to them, and then you can store any bination of those options like so:
- AB — 3
- BD — 10
- ACD — 13
Later, you can retrieve the value using bitwise operators:
if (opts & 1) console.log('A was selected');
if (opts & 2) console.log('B was selected');
if (opts & 4) console.log('C was selected');
if (opts & 8) console.log('D was selected');
Svelte uses bitmasks to track which values are dirty, i.e. what has changed since the ponent was last updated. Because of the 31 bit limit Tijmen described, a single bitmask would only let us have 31 variables in a ponent — plenty in most circumstances, but certainly not all. So ponent.$$.dirty
is an array of bitmasks.
This line of code...
ponent.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
...dirties the correct bit of the correct bitmask — the (i / 31) | 0
gives us the index of the bitmask, (1 << (i % 31))
gives us the value of the bit within that bitmask, and |=
sets the bit to 1, whatever its value was before.
The -1 is used as a sentinel value for indicating that the ponent wasn't previously dirty at all, so that Svelte can add it to the list of ponents that need to be updated in the next tick.
The dirty array is an array that stores multiple Boolean variables in an integer, also know as a bit array.
Integers in JavaScript are, by default, signed and 32-bit. The reason it only stores 31 bits per integer instead of 32 that because it's signed, the last bit, if set, makes the integer represent a negative number. I'm missing some context, but looking at the first if-statement, the code seems to reserve negative numbers for special cases.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744930751a4601721.html
评论列表(0条)