Hello all,
I hope you're sitting down... Grab a coffee too.
MotivationSo a good place to pick up this thought is from a thread Terry started, namely
REDIM _PRESERVE bug at
https://www.qb64.org/forum/index.php?topic=2416.0. Down in the replies, I wrote:
This is why I wish I started working on a really nice linked list library like a year ago. I have yet to develop this thought properly, but I suspect that linked lists can get us around this redim problem, and god willing, *all* problems surrounding arrays: mixing types and so on. I already use the technique on a case-by-case basis when I have a program that really demands a lot of its data - namely 3D levels and text editing to name my big two.
I got busy with this problem shortly after. Today I claim to have made good progress on creating a fast and universal library for storing and structuring data in QB64 programs. The approach doesn't attempt to solve the existing problems with REDIM _PRESERVE and its cousins. Instead, I erase that question entirely, along with many other questions that arise with it. The basic idea here is the linked list, which you can glimpse at Wikipedia:
https://en.wikipedia.org/wiki/Linked_list. The prototype introduced here goes a bit beyond that though, and word from our local science community likens this more to a "graph" than a list. Whatever we call it in the end won't matter I guess.
Hard Array v.s. Soft ArrayLet us define a "hard" array as a "traditional" array, as one would normally create in a program. While these are the best thing we have for structured and repetitious data, Terry points out that arrays, particularly of several dimensions, are clunky to reshape once they're carved out in memory. Nonetheless, the program must store its data
somewhere, and this prototype is no exception. The bare-bones data in a program is still stored in "hard" arrays, strictly one-dimensional, as in:
Now, if all a program needs is a simple one-dimensional array for a given data type, we're already done... But what if we want an array that mixes types, has an unequal number of rows per column, contains other arrays, and so on? This is solved by a new structure I call a
Soft Array. A soft array is a collection of
Elements that contain pointers to (i) data stored in hard arrays, and (ii) neighboring elements. Any given element has a unique identity, a variable indicating its data type, a variable containing an index in a hard array, and up to four connections with other elements:
Reference
AS LONG ' Pointer to hard array index
It turns out this is (more than) all one needs to conjure any complicated data structure one may imagine. Don't be deceived by the labels "North", "South", "East", "West" because the "landscape" available for element linkage is NOT a euclidean space. This is some kind of non-differentiable manifold... Maybe it's a "graph" after all, but I digress...
Data AssimilationThe "hard" storage arrays only contain unique data points. For example, to add a new integer into the data, the following function is executed internally:
TheReturn = -1
TheReturn = k
IntegerData
(UBOUND(IntegerData
)) = x
TheReturn
= UBOUND(IntegerData
) NewIntegerData = TheReturn
With the above optimization, the
one array that contains all (for instance) string data won't have multiple copies of the same field, such "Name".
Link TraversalNavigation through a soft array is less obvious than through a hard array. To be definite, we must completely do away with the idea of a FOR loop that steps through the array indices, and replace that notion with following pointers to the child elements until all elements have been touched.
For example, the simple procedure
is replaced by this recursive mess:
t = ""
k = SoftArray(x).FirstElement
t = t + ListElementsRecur$(0, k)
TheReturn
= TheReturn
+ SPACE$(i
) + Literal$
(x
) + CHR$(10) s = Elements(x).South
e = Elements(x).East
TheReturn = TheReturn + ListElementsRecur$(i + 2, e)
TheReturn = TheReturn + ListElementsRecur$(i, s)
ListElementsRecur$ = TheReturn
TheReturn = ""
TheReturn = StringData(Elements(x).Reference)
Literal$ = TheReturn
Conclusions (for now)I could go on and on about what this thing can do. You've already seen this idea implemented in a few of my works - this is my attempt to lift the good ideas out and export them for other uses. If pictures speak to you as much as words, the screenshot attached attempts to draw out what I've explained.
Now, without further delay, the full code as of now:
See post marked
as Best Answer.