OUT OF DATE; LAYERS IS MULTITHREADED NOW
Current layer processing
The Layers class is single threaded currently.
At initialization, it sets its variables and sorts provided marks into their layers.
When produceSpanData is called, Layers will press all layers together into a span data array.
It calls for a pressLayersBtwn on the entire text.
When patchSpanData is called, it is more complicated.
We do not want to patch the entire text, so we need to find the affected section of the span data array.
- First we find the char ranges affected by the marks and merge them.
- Then we find the char ranges that cleanly separate span data in the provided span data array.
- For each of these non-overlapping char ranges, re-press the span data with current layers.
- For each, add to the patch needed to change the provided span data array into an updated one.
- Once finished, reset the layer patches and return the span data patch.
In pressLayersBtwn, we need to take the existing layers and turn it into span data.
- Loop over layers from front to back.
-
- Loop over the remaining text ranges, starting with input args [begChar, endChar].
-
-
- Flatten marks that overlap with the remaining ranges and transform into span data.
-
-
- Deal with zero-size marks in a special case.
-
-
- Push these new spans onto structure layerSpans.
-
-
- Recalculate remaining text ranges from added spans.
- Exit all loops.
- Sort the layerSpans structure.
New layer processing
The single threaded part is the main issue to solve.
We can put up with complication, but not sloth; a lot of this processing is async-able.
Generally, here are some steps we can take toward async:
- Async patch as much as possible
- Use patch to do the initial "produceSpanData" calculation as well
- Add a DieCut structure to take the initial press and cut it into separate pieces
- Synchronize Manuscript's spanDataArray using setTimeout or something, 100ms or so
In order, with full multithreading, here is what we should do.
Let's look first by thread.
Main Thread
-
Layer initialization should be the same or close.
-
It may still sort the marks asynchronously, but that is not a priority.
-
When Layers.produceSpanData is called, it should return an empty spanDataBatchArray.
-
It will start another thread that is initializing span data.
-
Whenever Layers.synchronize is called, the spanDataBatchArray will be patched and patches reset.
-
Whenever initialization is done, it will go into holding mode.
-
If a patch is called for, before or after holding mode, Layers will add it to a patch queue.
-
The same processing will be used to patch spanDataBatchArray on Layers.synchronize.
-
Patches only be activated in order of arrival.
Mark Patch Thread
- When started, it is provided with a set of "layers" of marks.
- Its job is to find "cutpt"s using a DieCut structure (not sure if it will be an official structure).
- This DieCut can search through the marks to find a section that is not overlapping with marks.
- It reports this in a generator so the "press range", [begChar, endChar] of the section can be added to a queue.
- This thread calls the span patch thread to pressLayersBtwn the ranges in this queue.
- After initial DieCut is complete, this thread will begin calculating mark patches.
- After each mark patch is calculated from the add/rm/diff (patchFromAdd etc.), it will add to press range queue.
Span Patch thread
- This starts by taking a "press range" from the press range queue.
- It simply does pressLayerBtwn over this press range and returns the created span data in raw array.
- When the span patch thread finishes, it adds patches of span data to a span patch queue.
Synchronization
- There need be no true synchronization mutex; we can manage this through queues.
- First, whenever produceSpanData is called, it should be non-blocking main.
- Press ranges will be calculated in mark patch thread and added to press range queue.
- Span patches will be calculated in span patch thread and added to span patch queue.
- Main thread will perform span patch itself so it can synchronously update the batch array.