The snippet below is what gets generated when we do a npm run dev
on svelte
app.
function make_dirty(component, i) {
if (component.$$.dirty[0] === -1) {
dirty_components.push(component);
schedule_update();
component.$$.dirty.fill(0);
}
component.$$.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?
component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
Thanks
To 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 combination of those options like so:
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 component was last updated. Because of the 31 bit limit Tijmen described, a single bitmask would only let us have 31 variables in a component — plenty in most circumstances, but certainly not all. So component.$$.dirty
is an array of bitmasks.
This line of code...
component.$$.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 component wasn't previously dirty at all, so that Svelte can add it to the list of components that need to be updated in the next tick.