Hello @core-libs-dev <[email protected]>,

This is a follow up of one of my previous experience reports, a little over
a year ago.

https://mail.openjdk.org/pipermail/core-libs-dev/2024-August/127293.html

Just wanted to report more of my positive experiences with Gatherers,
specifically with a custom Gatherer that @Viktor Klang
<[email protected]> made for me called windowBy. Here is the
implementation below.

<TR> Gatherer<TR, ?, List<TR>> windowBy(Predicate<TR>
includeInCurrentWindow) {
    class State {
        ArrayList<TR> window;

        boolean integrate(TR element, Gatherer.Downstream<? super List<TR>>
downstream) {
            if (window != null && !includeInCurrentWindow.test(element)) {
                var result = Collections.unmodifiableList(window);
                window = null;
                if (!downstream.push(result))
                    return false;
            }

            if (window == null)
                window = new ArrayList<>();

            return window.add(element);
        }

        void finish(Gatherer.Downstream<? super List<TR>> downstream) {
            if (window != null) {
                var result = Collections.unmodifiableList(window);
                window = null;
                downstream.push(result);
            }
        }
    }
    return Gatherer.<TR, State, List<TR>>ofSequential(State::new,
State::integrate, State::finish);
}

Clean and simple.

Anyways, as for my experience report, a found a brand new way to use this
custom Gatherer -- event coalescing.

Sometimes, if consecutive events being streamed are of the same type, then
to reduce computation, you might be able to avoid doing more work by
grouping together the potential duplicates, then handling them separately
in a coalescing path. I'd much rather solve that problem than a caching
problem lol.

Anyways, here are the 2 examples where it served me well.


   1. Network Request Coalescing.
      1. When checking the availability of certain networks, I am now able
      to save some bandwidth by combining multiple, consecutive
requests within a
      certain time to a certain network. And since I am definitely bandwidth
      bound, that helps. Nothing I couldn't do before, but keeping it within
      Streams allowed me to avoid ripping out my old solution when it stopped
      being a good fit. I wish I could share the code, but it's not my right to
      share it.
   2. Path-Finding Algorithm -- Clustering
      1. This one is still a work in progress, so I may be speaking
      prematurely here. But I was so impressed that this is working thus far.
      Long story short, I am building a path-finding algorithm where,
if a set of
      points are close enough together, then they can be serviced as a
group, and
      thus, lower the total weight of servicing those nodes, as opposed to
      servicing them individually. Again, not done yet, so I might be
jumping the
      gun, but it worked so well for me out of the box, that I thought it was
      worth sharing.

Hopefully this bumps up windowBy on the triage list of potential pre-built
gatherers to add to the standard library. And thanks again to Viktor and
friends for putting this Gatherers library together -- it's a great
addition!

Thank you all for your time and consideration!
David Alayachew

Reply via email to