As I have written in this post 
<https://groups.google.com/forum/#!topic/leo-editor/hIDLXCwwITY>, my 
primary goals were not speed related. As a matter of fact I expected that 
new model would be in some areas even slower than Leo. I did hope however, 
that  overall performance would be much better than present Leo. But I've 
never dreamed that it would be so much faster. The speed came as 
a by-product, as a gift. 

In another thread Edward wrote that the prototype served its purpose, but 
the way I see it, its main purpose is totally missed. Right now, I don't 
feel much desire to continue developing the prototype. Somehow I feel it 
won't be accepted and it is useless to try. However, I am certain that it 
won't be too long before I continue some experiments in this direction.

The first experiments concerning the new data model I have made in July 
2017, right after I wrote functions for reading and writing external files. 
All these experiments can be found in leo-snippets repository. 

Later I have made an experiment using ClojureScript and electron to make a 
Leo using electron as GUI. Even later I have made the same experiment but 
this time using CoffeeScript. After that I have made some experiments using 
rust language to write a python extension that reads external files. 

So, I have written new data model several times, using several different 
languages and each time I wrote it I learned something new. Each model was 
better than the one before. 

I would like to share what I have learned so far. I am even considering an 
idea to write a book about it. Or, more likely I will write about it in my 
blog. Writing a book seems too big project at the moment, but who knows. I 
feel that this new data model has great potential and that it can be used 
in many other fields as well. I feel that it would be a great idea to 
rewrite it once again - this time completely in rust language and make it 
available as both the Python extension and Node extension. I have even 
installed a Windows 10 as a second OS on my new machine so that I can 
compile both for Windows and Linux. As the prototype shows new model is 
quite easily attached to any GUI. 

Edward seems to be not very fond of this new model. It may seem odd or 
complicated at first, but it is not.

More than once in this forum it was pointed out that Leo's outline is like 
a database. Let us accept this analogy for now and let me use some database 
terminology.

At the moment Leo keeps its data in the form of interconnected VNode 
instances. The result of reading outline is an array of VNodes which 
represent the top-level nodes in the outline. Their parent node is 
hiddenRootNode. To change the outline it is quite easy, just insert/append 
or remove VNode instance from the array of v.children or v.parents. That is 
all that you have to do in order to change the outline. That is very 
efficient operation that can't be any faster.

In the database world all data is kept in tables. Appending to the table is 
quite fast. Inserting and deleting from the table is also very fast 
operation. However, retrieving the data from database table can be 
sometimes slow. To speed up queries one usually needs to add some index to 
the database. Imagine searching for the owner of the specific phone number 
in a phone book, or for a specific word in a book. To find all occurrences 
one must read whole book. But if the book has word index at the end, it is 
very easy to look for a specific word. Also looking for a someones phone 
number in a phone book is easy if you know first and last name of the 
person. Adding suitable index to the database makes some queries that can 
use this index quite faster. On the other hand, every index added to 
database, slows down all inserts and deletes. The job of database designer 
is to make an optimal set of indexes so that all critical queries can run 
fast and that inserts and deletes are not too slow. Sometimes it is faster 
to drop the index, then perform bulk of insertions and/or deletions and 
then rebuild the index again.

Currently Leo is like a database with no indexes at all. We can modify the 
outline very fast, but when we need to query tree we have no other choice 
but to go from the start to the end. That makes drawing slow and very 
dependent on the outline size and number of expanded nodes. To speed 
drawing we have to add some indexes to Leo. My new data-model is nothing 
more than a database with just enough indexes to make all outline 
operations fast enough and traversing, searching, drawing very fast.

Edward can come up with another set of indexes, to achieve same performance 
as the prototype demonstrates. Perhaps, he can find even better suited set 
of indexes so that Leo becomes even faster than my prototype. The one thing 
I am sure is that speed can't be improved without some kind of indexes. And 
those indexes whatever they may be like, need to be updated every time 
outline changes. Currently Leo's data is totally unprotected. There is no 
way to find out about a change in the outline unless it is explicitly 
reported. And many scripts do not report change. The one possible solution 
is to replace both children and parents fields with user defined list 
instances that override all methods that modify list. Overridden methods 
should update both the list and indexes to keep them in sync. However, 
there may exist some scripts that set directly parents and children fields 
of vnode instances. Those scripts would broke Leo. In that case it would be 
necessary to turn fields 'children' and 'parents' into properties, to 
protect Leo's data from this kind of scripts.

There is a better solution. Let's use internally new data-model instead of 
vodes and positions. All of the operations that modify tree are already 
implemented in the prototype and all of them run at least ten times faster 
than current Leo commands. Undo/redo code can be substantially simpler and 
shorter, drawing can be very fast and the only thing that remain to be done 
is making scripts work as before. 

The easiest thing to do is to change execute-script command so that it 
first sync data from new model to c.hiddenRootNode, then execute script, 
and after executing script, resync data from c.hiddenRootNode back to new 
model. With this approach all scripts will continue to work just as they 
used to, and Leo's internals can be greatly simplified. 

I intend to write more about new model and to make some pictures to make it 
more understandable. That would also help me when (and if) I start 
rewriting it in Rust.

Vitalije

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.

Reply via email to