working java,python, js then added rust, then rewired java to j
This commit is contained in:
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
Copyright (c) 2011-2022 Reliancy LLC
|
||||
|
||||
Licensed under the GNU LESSER GENERAL PUBLIC LICENSE Version 3.
|
||||
You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html.
|
||||
You may not use this file except in compliance with the License.
|
||||
*/
|
||||
package com.reliancy.rec;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Spliterators;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.reliancy.util.Arrays;
|
||||
|
||||
/**
|
||||
* Iterator and Iterable for traversing {@link Slot} collections.
|
||||
*
|
||||
* <p>This class provides a unified interface for iterating over slots,
|
||||
* supporting both traditional iteration and Java 8+ Stream operations.
|
||||
*
|
||||
* Each header is iterated using local scope so you need to explictly specify an array in cases of inheritance.
|
||||
*
|
||||
* <h2>Type Parameters:</h2>
|
||||
* <ul>
|
||||
* <li>{@code S} - The slot type (must extend {@link Slot})</li>
|
||||
* <li>{@code H} - The header type (must extend {@link Hdr})</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Usage:</h2>
|
||||
* <pre>{@code
|
||||
* // For basic slots
|
||||
* Slots<Slot, Hdr> slots = new Slots<>(header);
|
||||
*
|
||||
* // For fields (Field extends Slot, Entity extends Hdr)
|
||||
* Slots<Field, Entity> fields = new Slots<>(entity);
|
||||
*
|
||||
* // Traditional iteration
|
||||
* for (Slot slot : slots) {
|
||||
* System.out.println(slot.getName());
|
||||
* }
|
||||
*
|
||||
* // Stream operations
|
||||
* fields.stream()
|
||||
* .filter(f -> f.getName().startsWith("user_"))
|
||||
* .forEach(f -> System.out.println(f.getName()));
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Utility Methods:</h2>
|
||||
* <p>The {@link #current()}, {@link #currentHeader()}, and {@link #currentIndex()} methods
|
||||
* provide context about the current iteration state. Each refers to the element returned
|
||||
* by the most recent call to {@link #next()} (or {@code null}/-1 before any call).
|
||||
* These are useful for inspection or conditional logic during iteration.
|
||||
*
|
||||
* @param <S> The slot type extending {@link Slot}
|
||||
* @param <H> The header type extending {@link Hdr}
|
||||
* @see Slot
|
||||
* @see Hdr
|
||||
* @see Iterable
|
||||
* @see Iterator
|
||||
* @see Stream
|
||||
*/
|
||||
public class Slots<S extends Slot> implements Iterator<S>, Iterable<S> {
|
||||
public static Slots<Slot> of(Hdr... headers){
|
||||
return new Slots<>(headers);
|
||||
}
|
||||
public static interface Selector{
|
||||
boolean select(Slot s);
|
||||
}
|
||||
public static final Selector SELECT_ALL=new Selector(){
|
||||
public boolean select(Slot slot){
|
||||
return true;
|
||||
}
|
||||
};
|
||||
public static class SELECT_INCLUDING implements Selector{
|
||||
int flags;
|
||||
public SELECT_INCLUDING(int flags){
|
||||
this.flags=flags;
|
||||
}
|
||||
public boolean select(Slot slot){
|
||||
return (slot.getFlags() & flags) != 0;
|
||||
}
|
||||
}
|
||||
public static class SELECT_EXCLUDING implements Selector{
|
||||
int flags;
|
||||
public SELECT_EXCLUDING(int flags){
|
||||
this.flags=flags;
|
||||
}
|
||||
public boolean select(Slot slot){
|
||||
return (slot.getFlags() & flags) == 0;
|
||||
}
|
||||
}
|
||||
Hdr[] headers;
|
||||
Selector selector;
|
||||
// iterator state
|
||||
int h_next;
|
||||
List<Slot> h_slots;
|
||||
int s_next;
|
||||
int s_current_index;
|
||||
S s_current_item;
|
||||
Hdr s_current_header;
|
||||
/**
|
||||
* Creates a new Slots iterator.
|
||||
*
|
||||
* @param headers The headers containing slots to iterate over
|
||||
*/
|
||||
public Slots(Hdr... headers) {
|
||||
this.headers=headers;
|
||||
rewind();
|
||||
}
|
||||
public Slots<S> considering(Hdr... headers){
|
||||
this.headers=headers;
|
||||
rewind();
|
||||
return this;
|
||||
}
|
||||
public Slots<S> selectBy(Selector selector){
|
||||
this.selector=selector;
|
||||
rewind();
|
||||
return this;
|
||||
}
|
||||
public Slots<S> clone(){
|
||||
Slots<S> cloned =new Slots<>(headers);
|
||||
if(selector!=null){
|
||||
cloned.selectBy(selector);
|
||||
}
|
||||
return cloned;
|
||||
}
|
||||
/**
|
||||
* Filters fields to include only those with the specified flags set.
|
||||
*
|
||||
* @param flags The flag mask to match
|
||||
* @return This Fields instance for method chaining
|
||||
*/
|
||||
public Slots<S> including(int flags) {
|
||||
selectBy(new Slots.SELECT_INCLUDING(flags));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters fields to exclude those with the specified flags set.
|
||||
*
|
||||
* @param flags The flag mask to exclude
|
||||
* @return This Fields instance for method chaining
|
||||
*/
|
||||
public Slots<S> excluding(int flags) {
|
||||
selectBy(new Slots.SELECT_EXCLUDING(flags));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Slots<S> rewind(){
|
||||
h_next=0;
|
||||
h_slots=headers.length>0?headers[h_next].getOwnSlots():new ArrayList<Slot>();
|
||||
s_next=-1;
|
||||
seekNext();
|
||||
// above seeknext is not consuming so we clear the current state
|
||||
s_current_index=-1;
|
||||
s_current_item=null;
|
||||
s_current_header=(0<=h_next && h_next<headers.length)?headers[h_next]:null;
|
||||
return this;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void seekNext(){
|
||||
// Iterate through slots in current header, then move to next header if needed
|
||||
S last_item=(0<=s_next && s_next<h_slots.size())?(S)h_slots.get(s_next):null;
|
||||
Hdr last_header=(0<=h_next && h_next<headers.length)?headers[h_next]:null;
|
||||
while(h_next < headers.length){
|
||||
// Try to find next matching slot in current header
|
||||
while(s_next + 1 < h_slots.size()){
|
||||
s_next+=1;
|
||||
Slot slot = (Slot)h_slots.get(s_next);
|
||||
if(selector == null || selector.select(slot)){
|
||||
// we found next item - lock in current values
|
||||
s_current_item=last_item;
|
||||
s_current_header=last_header;
|
||||
s_current_index+=1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Current header's slots exhausted, move to next header
|
||||
h_next++;
|
||||
if(h_next < headers.length){
|
||||
h_slots = headers[h_next].getOwnSlots();
|
||||
s_next = -1;
|
||||
}else{
|
||||
h_slots = new ArrayList<Slot>();
|
||||
s_next = -1;
|
||||
// we are done -lock in last item
|
||||
s_current_item=last_item;
|
||||
s_current_header=last_header;
|
||||
s_current_index+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ========================================================================
|
||||
// Iterator Implementation
|
||||
// ========================================================================
|
||||
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
* @throws java.util.NoSuchElementException if the iteration has no more elements
|
||||
*/
|
||||
@Override
|
||||
public S next() {
|
||||
if(!hasNext()) throw new java.util.NoSuchElementException();
|
||||
seekNext();
|
||||
return s_current_item;
|
||||
}
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return 0<=s_next && s_next < h_slots.size();
|
||||
}
|
||||
|
||||
public S current(){
|
||||
return s_current_item;
|
||||
}
|
||||
public Hdr currentHeader(){
|
||||
return s_current_header;
|
||||
}
|
||||
/**
|
||||
* Returns the index of the last element returned by {@link #next()}.
|
||||
*
|
||||
* <p>Returns -1 if {@link #next()} has not been called yet (i.e., before the first
|
||||
* call to {@link #next()}). After each call to {@link #next()}, this value is
|
||||
* incremented to reflect the index of the element that was just returned.
|
||||
*
|
||||
* @return the index of the last returned element, or -1 if no elements have been returned yet
|
||||
*/
|
||||
public int currentIndex(){
|
||||
return s_current_index;
|
||||
}
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation).
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove} operation
|
||||
* is not supported by this iterator
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("forward only immutable view");
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Iterable Implementation
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* Returns an iterator over elements of type {@code S}.
|
||||
*
|
||||
* @return an Iterator
|
||||
*/
|
||||
@Override
|
||||
public Iterator<S> iterator() {
|
||||
return clone();
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Stream Support
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code Stream} with this collection as its source.
|
||||
*
|
||||
* <p>This method allows the slots to be processed using Java 8+ Stream API:
|
||||
* <pre>{@code
|
||||
* slots.stream()
|
||||
* .filter(s -> s.getName().startsWith("user_"))
|
||||
* .map(Slot::getName)
|
||||
* .collect(Collectors.toList());
|
||||
* }</pre>
|
||||
*
|
||||
* @return a sequential Stream over the slots
|
||||
*/
|
||||
public Stream<S> stream() {
|
||||
return StreamSupport.stream(
|
||||
Spliterators.spliteratorUnknownSize(this, 0),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a possibly parallel {@code Stream} with this collection as its source.
|
||||
*
|
||||
* <p>It is allowable for this method to return a sequential stream.
|
||||
*
|
||||
* @return a possibly parallel Stream over the slots
|
||||
*/
|
||||
public Stream<S> parallelStream() {
|
||||
return StreamSupport.stream(
|
||||
Spliterators.spliteratorUnknownSize(this, 0),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user