Skip to content

Commit

Permalink
Merge branch 'master' into use-kotlin
Browse files Browse the repository at this point in the history
  • Loading branch information
popematt authored Nov 16, 2023
2 parents 4689ee9 + 0d0258c commit 59b5617
Show file tree
Hide file tree
Showing 6 changed files with 314 additions and 239 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5
uses: github/codeql-action/init@689fdc5193eeb735ecb2e52e819e3382876f93f4 # v2.22.6
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -52,7 +52,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5
uses: github/codeql-action/autobuild@689fdc5193eeb735ecb2e52e819e3382876f93f4 # v2.22.6

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -66,4 +66,4 @@ jobs:
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5
uses: github/codeql-action/analyze@689fdc5193eeb735ecb2e52e819e3382876f93f4 # v2.22.6
2 changes: 1 addition & 1 deletion .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ jobs:

# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5
uses: github/codeql-action/upload-sarif@689fdc5193eeb735ecb2e52e819e3382876f93f4 # v2.22.6
with:
sarif_file: results.sarif
122 changes: 122 additions & 0 deletions src/com/amazon/ion/impl/_Private_RecyclingQueue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package com.amazon.ion.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* A queue whose elements are recycled. This queue will be extended and iterated frequently.
* @param <T> the type of elements stored.
*/
public class _Private_RecyclingQueue<T> {

/**
* Factory for new queue elements.
* @param <T> the type of element.
*/
public interface ElementFactory<T> {
/**
* @return a new instance.
*/
T newElement();
}

@FunctionalInterface
public interface Recycler<T> {
/**
* Re-initialize an element
*/
void recycle(T t);
}

/**
* Iterator for the queue.
*/
private class ElementIterator implements Iterator<T> {
int i = 0;
@Override
public boolean hasNext() {
return i <= currentIndex;
}

@Override
public T next() {
return elements.get(i++);
}
}

private final ElementIterator iterator;
private final List<T> elements;
private final ElementFactory<T> elementFactory;
private int currentIndex;
private T top;

/**
* @param initialCapacity the initial capacity of the underlying collection.
* @param elementFactory the factory used to create a new element on {@link #push()} when the queue has
* not previously grown to the new depth.
*/
public _Private_RecyclingQueue(int initialCapacity, ElementFactory<T> elementFactory) {
elements = new ArrayList<T>(initialCapacity);
this.elementFactory = elementFactory;
currentIndex = -1;
iterator = new ElementIterator();
}

public void truncate(int index) {
currentIndex = index;
}

public T get(int index) {
return elements.get(index);
}

/**
* Pushes an element onto the top of the queue, instantiating a new element only if the queue has not
* previously grown to the new depth.
* @return the element at the top of the queue after the push. This element must be initialized by the caller.
*/
public int push(Recycler<T> recycler) {
currentIndex++;
if (currentIndex >= elements.size()) {
top = elementFactory.newElement();
elements.add(top);
} else {
top = elements.get(currentIndex);
}
recycler.recycle(top);
return currentIndex;
}

/**
* Reclaim the current element.
*/
public void remove() {
currentIndex = Math.max(-1, currentIndex - 1);
}

public Iterator<T> iterate() {
iterator.i = 0;
return iterator;
}

/**
* @return true if the queue is empty; otherwise, false.
*/
public boolean isEmpty() {
return currentIndex < 0;
}

/**
* Reset the index and make the queue reusable.
*/
public void clear() {
currentIndex = -1;
}

/**
* @return the number of elements within the queue.
*/
public int size() {
return currentIndex + 1;
}
}
87 changes: 83 additions & 4 deletions src/com/amazon/ion/impl/_Private_RecyclingStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;

/**
* A stack whose elements are recycled. This can be useful when the stack needs to grow and shrink
* frequently and has a predictable maximum depth.
* @param <T> the type of elements stored.
*/
public final class _Private_RecyclingStack<T> {
public final class _Private_RecyclingStack<T> implements Iterable<T> {
public $Iterator stackIterator;
@Override
public ListIterator<T> iterator() {
if (stackIterator != null) {
stackIterator.cursor = _Private_RecyclingStack.this.currentIndex;
} else {
stackIterator = new $Iterator();
}
return stackIterator;
}

/**
* Factory for new stack elements.
Expand All @@ -22,18 +34,26 @@ public interface ElementFactory<T> {
T newElement();
}

@FunctionalInterface
public interface Recycler<T> {
/**
* Re-initialize an element
*/
void recycle(T t);
}

private final List<T> elements;
private final ElementFactory<T> elementFactory;
private int currentIndex;
private T top;

/**
* @param initialCapacity the initial capacity of the underlying collection.
* @param elementFactory the factory used to create a new element on {@link #push()} when the stack has
* @param elementFactory the factory used to create a new element on {@link #push(Recycler)} when the stack has
* not previously grown to the new depth.
*/
public _Private_RecyclingStack(int initialCapacity, ElementFactory<T> elementFactory) {
elements = new ArrayList<T>(initialCapacity);
elements = new ArrayList<>(initialCapacity);
this.elementFactory = elementFactory;
currentIndex = -1;
top = null;
Expand All @@ -44,14 +64,15 @@ public _Private_RecyclingStack(int initialCapacity, ElementFactory<T> elementFac
* previously grown to the new depth.
* @return the element at the top of the stack after the push. This element must be initialized by the caller.
*/
public T push() {
public T push(Recycler<T> recycler) {
currentIndex++;
if (currentIndex >= elements.size()) {
top = elementFactory.newElement();
elements.add(top);
} else {
top = elements.get(currentIndex);
}
recycler.recycle(top);
return top;
}

Expand Down Expand Up @@ -92,4 +113,62 @@ public boolean isEmpty() {
public int size() {
return currentIndex + 1;
}

private class $Iterator implements ListIterator<T> {
private int cursor;

@Override
public boolean hasNext() {
return cursor >= 0;
}

@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
// post-decrement because "next" is where the cursor is
return _Private_RecyclingStack.this.elements.get(cursor--);
}

@Override
public boolean hasPrevious() {
return cursor + 1 <= _Private_RecyclingStack.this.currentIndex;
}

@Override
public T previous() {
if (!hasPrevious()) {
throw new NoSuchElementException();
}
// pre-increment: "next" is where the cursor is, so "previous" is upward in stack
return _Private_RecyclingStack.this.elements.get(++cursor);
}

@Override
public int nextIndex() {
return cursor;
}

@Override
public int previousIndex() {
return cursor + 1;
}

@Override
public void remove() {
throw new UnsupportedOperationException();
}

@Override
public void set(T t) {
throw new UnsupportedOperationException();
}

@Override
public void add(T t) {
throw new UnsupportedOperationException();
}
}

}
Loading

0 comments on commit 59b5617

Please sign in to comment.