Github user mmiklavc commented on a diff in the pull request:

    https://github.com/apache/metron/pull/899#discussion_r161912600
  
    --- Diff: 
metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/MathFunctions.java
 ---
    @@ -220,4 +219,156 @@ public Object apply(List<Object> args) {
           }
         }
       }
    +
    +  @Stellar(namespace = "BOYERMOORE"
    +      , name = "ADD"
    +      , description = "Adds value to a Boyer-Moore list. 
[Boyer-Moore](https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm)"
    +      , params = {
    +        "state - state holder for list of values. If null, add will 
initialize a new state value.",
    +        "value(s) - single object or list of values to add to the state 
object."
    +      }
    +      , returns = "Current state of the Boyer-Moore algorithm representing 
the current value that"
    +      + "holds a plurality across all values added thus far."
    +  )
    +  public static class BoyerMooreAdd extends BaseStellarFunction {
    +
    +    @Override
    +    public Object apply(List<Object> args) {
    +      if (args.size() < 2) {
    +        throw new IllegalArgumentException(
    +            "Must pass an initial state (may be null) and at least one 
value to add to the list");
    +      } else {
    +        BoyerMooreState state = ConversionUtils.convert(args.get(0), 
BoyerMooreState.class);
    +        if (state == null) {
    +          state = new BoyerMooreState();
    +        }
    +        Object secondArg = args.get(1);
    +        if (secondArg instanceof List) {
    +          state.addAll((List) secondArg);
    +        } else {
    +          state.add(secondArg);
    +        }
    +        return state;
    +      }
    +    }
    +  }
    +
    +  public static class BoyerMooreState {
    +    private Long counter;
    +    private Object m;
    +
    +    public BoyerMooreState() {
    +      counter = 0L;
    +    }
    +
    +    public BoyerMooreState(Optional<List<BoyerMooreState>> previousStates, 
Optional<BoyerMooreState> currentState) {
    +      this();
    +      currentState.ifPresent(boyerMooreState -> {
    +        m = boyerMooreState.getPlurality();
    +        counter = boyerMooreState.getCounter();
    +      });
    +      for (BoyerMooreState state : previousStates.orElse(new 
ArrayList<>())) {
    +        Object plurality = state.getPlurality();
    +        Long pluralityCount = state.getCounter();
    +        add(plurality, pluralityCount);
    +      }
    +    }
    +
    +    public Object add(Object item) {
    +      if (item != null) {
    +        if (counter == 0) {
    +          m = item;
    +          counter = 1L;
    +        } else if (item.equals(m)) {
    +          counter++;
    +        } else {
    +          counter--;
    +        }
    +      }
    +      return m;
    +    }
    +
    +    public Object add(Object item, Long counter) {
    +      if (item != null) {
    +        if (this.counter == 0) {
    +          m = item;
    +          this.counter = counter;
    --- End diff --
    
    It's true, I make no effort to massage data types here - if you want to 
interpret a 1 as a string "1", then they will be considered distinct. I didn't 
have a suitable mechanism for determining types. I thought it was reasonable 
for a user to be able to make that type cast as part of their Stellar 
expression building, but I'm certainly open to suggestions.


---

Reply via email to