Skip to content

Commit

Permalink
Use sparse cache instead of full getItems() eclipse-platform#882
Browse files Browse the repository at this point in the history
  • Loading branch information
basilevs committed Nov 12, 2023
1 parent eaa5e60 commit a7a0685
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -794,12 +794,8 @@ public int getItemCount () {
public TreeItem getItem (int index) {
checkWidget();
if (index < 0) error (SWT.ERROR_INVALID_RANGE);
// It may seem that requesting GTK for an item by index is quicker,
// but it has O(N) execution time and cache of all children amortizes that.
// This avoids quadratic execution time on traversals
TreeItem[] items = getCache().getItems();
if (index >= items.length) error (SWT.ERROR_INVALID_RANGE);
return items[index];
if (index >= getCache().getItemCount()) error (SWT.ERROR_INVALID_RANGE);
return getCache().getItem(index);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
* @since 3.125**/
class TreeItemCache {
final TreeItem owner;
private TreeItem[] children;
private TreeItem[] allChildren;
private final ArrayList<TreeItem> sparseChildren = new ArrayList<>();
private int itemCount = -1;

TreeItemCache(TreeItem owner) {
Expand All @@ -35,16 +36,34 @@ int getItemCount() {
return itemCount;
}

TreeItem getItem(int index) {
if (sparseChildren.size() > index && sparseChildren.get(index) != null) {
return sparseChildren.get(index);
} else {
int newSize = Math.max(index + 1, itemCount);
int extraSize = newSize - sparseChildren.size();
if (extraSize > 0) {
sparseChildren.addAll(Collections.nCopies(extraSize, null));
}
TreeItem result = owner.parent._getItem(owner.handle, index);
sparseChildren.set(index, result);
return result;
}
}

TreeItem[] getItems() {
if (children == null) {
children = owner.parent.getItems(owner.handle);
itemCount = children.length;
if (allChildren == null) {
allChildren = owner.parent.getItems(owner.handle);
sparseChildren.clear();
sparseChildren.addAll(Arrays.asList(allChildren));
itemCount = allChildren.length;
}
return children;
return allChildren;
}

public void reset() {
itemCount = -1;
children = null;
allChildren = null;
sparseChildren.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,6 @@ void depthFirstTraverse(TreeItem parent) {
*/
private double measureNanos(Runnable operation) {
// warmup and calibration - we measure, how many iterations we can approximately do in a second

long warmupStop = System.nanoTime() + TimeUnit.SECONDS.toNanos(1);
long iterationCount = 0;
while (System.nanoTime() < warmupStop) {
Expand Down

0 comments on commit a7a0685

Please sign in to comment.