|
Cluster Arrays |
A cluster array in Sheerpower is a powerful data
structure that functions like an in-memory spreadsheet, containing
rows and columns of data. They are ideal for handling collections
of related information efficiently. Like vectors in other languages,
cluster arrays do not require preallocation—they grow automatically
as needed. Sheerpower provides a rich set of built-in features for
working with this data, allowing operations such as sorting, filtering,
and searching, much like you would in a database.
This `inventory` cluster holds multiple records (rows), each with the same set of fields (columns).
| item_id$ | product_name$ | quantity | price |
|---|---|---|---|
| WID-001 | Standard Widget | 150 | 19.99 |
| GAD-002 | Super Gadget | 75 | 29.95 |
| DOO-003 | Doodad Pro | 200 | 9.50 |
With enough RAM and pagefile space, cluster arrays can support up to one billion rows with key lookup speeds of millions per second.
First, you define the structure of your cluster. Then, you can add
records (rows) to it using the add cluster statement.
Sheerpower keeps track of a current row within
the cluster array. When you add a new record, that new record
automatically becomes the current row. To work with a different
record, you must first make it current using the
set cluster statement.
| item_id$ | product_name$ | |
|---|---|---|
| WID-001 | Standard Widget | |
| ⇒ | GAD-002 | Super Gadget |
| DOO-003 | Doodad Pro |
After set cluster inventory: row 2, the second
row is now the current one.
Modifying a record is simple: first make the record current, then assign a new value to its field.
Deleting records is also straightforward. For a detailed guide on removing rows, see Reset Cluster.
To process every record in a cluster array, you use a two-step pattern. This design is powerful because it separates the act of gathering/filtering data from the act of processing it.
collect ... end collect: This block
builds a temporary collection (or view) of your data. This is
where you do all your filtering (include/exclude)
and sorting.
for each ... next: This block then
loops through the temporary collection you just created.
There is no limit keyword inside collect cluster.
This is by design — a limit applied before sorting would select arbitrary
rows, not the top or bottom N values.
The correct pattern is to sort in the collect block, then use
a counter with exit for in the for each loop:
This guarantees the sort completes across the full dataset before the top N rows are selected.
Use unique with collect cluster to create a
collected view containing one row for each distinct value of a field.
For each distinct field value, the first matching row in cluster file order becomes the representative row for that group.
The underlying cluster is not changed. The size() function
still returns the total number of rows in the cluster, including
duplicates. To obtain the number of distinct values, use
_extracted after the end collect statement.
Distinct values and their occurrence counts come directly from the field's hash index. As rows are added to the cluster, the index maintains a count for each indexed value.
Because this information already exists, unique does not
need to scan the cluster or count duplicate rows at collect time. Its
work does not increase merely because a value occurs many times.
Inside the collect cluster block,
_extracted contains the occurrence count for the current
group. It tells how many cluster rows have the current distinct field
value.
After end collect, _extracted contains the
number of distinct values retained in the collected view.
The following example creates one collected row for each distinct word and stores the word's frequency in the representative row:
Inside the block, _extracted is the number of times the
current word occurs. After the block, it is the number of distinct
words in the collected view.
That single block performs the equivalent of a
GROUP BY operation together with a
COUNT for every group.
Unique grouping takes place before include and
exclude expressions are evaluated.
Each expression is evaluated once for each distinct value, using its
representative row. The group's complete occurrence count is available
as _extracted. This makes group-level filtering a
one-line operation.
For example, the following collection retains one representative row for every city name that occurs more than once:
After end collect, the collected view contains one row for
each repeated city name. At that position, _extracted
contains the number of repeated city names retained in the view.
Sheerpower provides built-in functions that can instantly calculate aggregate values across an entire cluster array field, eliminating the need for manual loops.
The findrow() function is highly optimized to perform
millions of lookups per second. It returns the row number of the
first record that matches your search criteria and make the row current, or 0 if no match
is found. The findrow() function works with any Sheerpower data type.
findrow(), the
field you search on is automatically optimized as a key field for
future lookups, making subsequent searches even faster. This
happens dynamically without any need for manual index configuration.
A successful findrow() automatically makes the row current.
findrow(), see High-speed Lookups with Clusters: FINDROW(), FINDVALUE(), and FINDVALUE$().cluster and populate rows
with add cluster and end add.set cluster statement moves the current row
pointer to target a specific record.collect ... end collect to filter and sort data,
followed by for each ... next to iterate through results.stats$sum(), stats$max(), and
stats$min() provide instant
aggregate calculations.findrow() enables high-speed searching and
automatically optimizes the searched field for future lookups.findrow() calls make the found row
current automatically.|
Hide Description
|
|
|
Enter or modify the code below, and then click on RUN |
|
Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use. |