Full Code of cnuernber/ham-fisted for AI

master d2f7171293f8 cached
198 files
2.0 MB
630.3k tokens
2676 symbols
1 requests
Download .txt
Showing preview only (2,096K chars total). Download the full file or copy to clipboard to get everything.
Repository: cnuernber/ham-fisted
Branch: master
Commit: d2f7171293f8
Files: 198
Total size: 2.0 MB

Directory structure:
gitextract_zg1q5mjk/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── .mise.toml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.clj
├── codegen/
│   └── gen_prim_invoke.clj
├── deps.edn
├── dev/
│   ├── resources/
│   │   └── logback.xml
│   └── src/
│       ├── ham_fisted/
│       │   ├── analysis.clj
│       │   ├── benchmark.clj
│       │   └── protocol_perf.clj
│       └── perftest.clj
├── docs/
│   ├── Reductions.html
│   ├── css/
│   │   └── default.css
│   ├── ham-fisted.api.html
│   ├── ham-fisted.bloom-filter.html
│   ├── ham-fisted.defprotocol.html
│   ├── ham-fisted.fjp.html
│   ├── ham-fisted.function.html
│   ├── ham-fisted.hlet.html
│   ├── ham-fisted.iterator.html
│   ├── ham-fisted.lazy-noncaching.html
│   ├── ham-fisted.mut-map.html
│   ├── ham-fisted.primitive-invoke.html
│   ├── ham-fisted.process.html
│   ├── ham-fisted.profile.html
│   ├── ham-fisted.protocols.html
│   ├── ham-fisted.reduce.html
│   ├── ham-fisted.set.html
│   ├── ham-fisted.spliterator.html
│   ├── highlight/
│   │   └── solarized-light.css
│   ├── index.html
│   └── js/
│       └── page_effects.js
├── java/
│   └── ham_fisted/
│       ├── ArrayHelpers.java
│       ├── ArrayImmutList.java
│       ├── ArrayLists.java
│       ├── ArraySection.java
│       ├── BatchReducer.java
│       ├── BatchedList.java
│       ├── BiFunctions.java
│       ├── BlockSplitBloomFilter.java
│       ├── Casts.java
│       ├── ChunkedList.java
│       ├── CljHash.java
│       ├── ConstList.java
│       ├── ConsumerAccumulators.java
│       ├── Consumers.java
│       ├── CtxIter.java
│       ├── DoubleMutList.java
│       ├── FJTask.java
│       ├── FMapEntry.java
│       ├── ForkJoinPatterns.java
│       ├── HashBase.java
│       ├── HashMap.java
│       ├── HashNode.java
│       ├── HashProvider.java
│       ├── HashProviders.java
│       ├── HashSet.java
│       ├── IAMapEntry.java
│       ├── IAPersistentMap.java
│       ├── IAPersistentSet.java
│       ├── IATransientMap.java
│       ├── IATransientSet.java
│       ├── ICollectionDef.java
│       ├── IFnDef.java
│       ├── IMap.java
│       ├── IMutList.java
│       ├── ISeqDef.java
│       ├── ISet.java
│       ├── ITypedReduce.java
│       ├── ImmutList.java
│       ├── ImmutSort.java
│       ├── IndexedConsumer.java
│       ├── IndexedDoubleConsumer.java
│       ├── IndexedLongConsumer.java
│       ├── IntegerOps.java
│       ├── Iter.java
│       ├── LazyChunkedSeq.java
│       ├── LinkedHashMap.java
│       ├── LinkedHashNode.java
│       ├── LongAccum.java
│       ├── LongHashBase.java
│       ├── LongHashMap.java
│       ├── LongHashNode.java
│       ├── LongMutList.java
│       ├── MapFn.java
│       ├── MapForward.java
│       ├── MapSetOps.java
│       ├── MergeIterator.java
│       ├── MethodImplCache.java
│       ├── MutList.java
│       ├── MutTreeList.java
│       ├── MutableMap.java
│       ├── ObjArray.java
│       ├── ParallelOptions.java
│       ├── PartitionByInner.java
│       ├── PersistentHashMap.java
│       ├── PersistentHashSet.java
│       ├── PersistentLongHashMap.java
│       ├── PersistentVector.java
│       ├── ROHashMap.java
│       ├── ROHashSet.java
│       ├── ROLongHashMap.java
│       ├── RandomAccessSpliterator.java
│       ├── RangeList.java
│       ├── Ranges.java
│       ├── Reducible.java
│       ├── Reductions.java
│       ├── ReindexList.java
│       ├── ReverseList.java
│       ├── SetOps.java
│       ├── StringCollection.java
│       ├── Sum.java
│       ├── Transformables.java
│       ├── TransientHashMap.java
│       ├── TransientHashSet.java
│       ├── TransientList.java
│       ├── TransientLongHashMap.java
│       ├── TreeList.java
│       ├── TreeListBase.java
│       ├── TypedList.java
│       ├── TypedNth.java
│       ├── UnsharedHashMap.java
│       ├── UnsharedHashSet.java
│       ├── UnsharedLongHashMap.java
│       └── UpdateValues.java
├── resources/
│   └── clj-kondo.exports/
│       └── cnuernber/
│           └── ham-fisted/
│               ├── config.edn
│               └── hooks/
│                   └── ham_fisted.clj_kondo
├── results/
│   ├── .keepme
│   ├── concatv.edn
│   ├── d00905c-chrisn-lt3-jdk-1.8.0_312.edn
│   ├── d00905c-chrisn-lt3-jdk-17.0.1.edn
│   ├── general-hashmap.edn
│   ├── persistent-vector.edn
│   ├── random-update.edn
│   ├── sort-by.edn
│   ├── typed-parallel-reductions.edn
│   ├── typed-reductions-intel.edn
│   ├── typed-reductions.edn
│   ├── union-disj.edn
│   ├── union-overlapping.edn
│   ├── union-reduce-transient.edn
│   ├── union-reduce.edn
│   ├── update-values.edn
│   └── vec-equals.edn
├── scripts/
│   ├── benchmark
│   ├── compile
│   ├── deploy
│   ├── enable-jdk17
│   ├── install
│   ├── koacha-test
│   ├── lint
│   ├── reformat
│   └── run-tests
├── src/
│   └── ham_fisted/
│       ├── alists.clj
│       ├── api.clj
│       ├── bloom_filter.clj
│       ├── caffeine.clj
│       ├── datatypes.clj
│       ├── defprotocol.clj
│       ├── fjp.clj
│       ├── function.clj
│       ├── hlet.clj
│       ├── impl.clj
│       ├── iterator.clj
│       ├── language.clj
│       ├── lazy_caching.clj
│       ├── lazy_noncaching.clj
│       ├── mut_map.clj
│       ├── primitive_invoke.clj
│       ├── print.clj
│       ├── process.clj
│       ├── profile.clj
│       ├── protocols.clj
│       ├── reduce.clj
│       ├── set.clj
│       ├── spliterator.clj
│       └── thread_local.clj
├── test/
│   └── ham_fisted/
│       ├── api_test.clj
│       ├── bloom_filter_test.clj
│       ├── cast_test.clj
│       ├── defprotocol_test/
│       │   ├── examples.clj
│       │   ├── hash_collisions_test.clj
│       │   ├── more_examples.clj
│       │   └── other_test.clj
│       ├── defprotocol_test.clj
│       ├── fjp_test.clj
│       ├── hash_map_test.clj
│       ├── hlet_test.clj
│       ├── parallel_test.clj
│       ├── persistent_vector_test.clj
│       ├── test_setup.clj
│       └── vec_like_test.clj
├── tests.edn
└── topics/
    └── Reductions.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
github: cnuernber


================================================
FILE: .github/workflows/test.yml
================================================
name: Automated tests

on:
  push:

jobs:
  test:
    runs-on: ubuntu-22.04
    steps:
    - uses: actions/checkout@v3
    - name: Restore cached dependencies
      uses: actions/cache/restore@v3
      with:
        path: |
           ~/.m2/repository
           ~/.deps.clj
        key: cljdeps-${{ hashFiles('deps.edn') }}
    - name: Mise-en-place setup
      uses: jdx/mise-action@v2
      with:
        install: true
        cache: true
    - name: Setup Clojure
      uses: DeLaGuardo/setup-clojure@12.1
      with:
        cli: 1.11.1.1413
    - name: Run automated tests - Java 11
      run: |
        mise use java@corretto-11
        java -version
        scripts/run-tests
    - name: Run automated tests - Java 17
      run: |
        mise use java@corretto-17
        java -version
        scripts/run-tests
    - name: Run automated tests - Java 19
      run: |
        mise use java@corretto-19
        java -version
        scripts/run-tests
    - name: Run automated tests - Java 21
      run: |
        mise use java@corretto-21
        java -version
        scripts/run-tests
    - name: Run automated tests - Java 22
      run: |
        mise use java@corretto-22
        java -version
        scripts/run-tests
    - name: Cache dependencies
      uses: actions/cache@v3
      with:
        path: |
           ~/.m2/repository
           ~/.deps.clj
        key: cljdeps-${{ hashFiles('deps.edn') }}
        restore-keys: cljdeps-


================================================
FILE: .gitignore
================================================
.cpcache
target
.nrepl-port
pom.xml
*.asc
issue-data
jdk-*
.clj-kondo
.lsp
.dir-locals.el


================================================
FILE: .mise.toml
================================================
[tools]
java = "corretto-8"


================================================
FILE: CHANGELOG.md
================================================
# 3.029
 * Much more thorough support for spliterators and forkjoinpool. See spliterator and fjp namespaces
   respectively.
 
# 3.025
 * bloom filters handle java.time.Instants automatically
 
# 3.023
 * fix - process/launch invalid stdout for very quick processes.
 
# 3.022
 * merge-iterable returns a seq-iterable so it plays nice with the REPL.
 
# 3.020
 * seq-iterables cannot be `counted?`
 
# 3.019
 * Fix bug in with empty sequences and pmap-io.
 
# 3.018
 * iterator/merge-iterable has to be stable w/r/t iterator order - leftmost wins.
 
# 3.017
 * Fix for concat, apply-concat to make their iterators a bit lazier than they were before.
 
# 3.015
 * Fix for issue 10 - partition-all works different.
 * new partition fns - partition-by-cost and partition-by-comparator.
 * new iterator fns - iter-take-while, wrap-iter, iter-take
 
# 3.013
 * iterators created via iterator/once-iterable and iterator/iterable are as lazy as possible
   avoiding certain types of lookahead and hanging behavior.
 
# 3.010
 * Reduce require time for defprotocol by avoiding primitive-invoke namespace.
 
# 3.009
 * Issue fixed in process namespace.
 
# 3.008
 * [issue 22](https://github.com/cnuernber/ham-fisted/issues/21) - better clj-condo support.
 * new [process](https://cnuernber.github.io/ham-fisted/ham-fisted.process.html) namespace for 
   launching and controlling sub processes.
 
# 3.003
 * New functions and docs added to 'iterator' namespace.
 
# 3.000
 * All protocols replaced with hamf's defprotocol impl.
 
# 2.039
 * Slightly faster protocol dispatch as avoids instance check for interface impl in favor of
   only using map lookup.
 * Implementation of cond that can be used in functions that need to avoid boxing.
 
# 2.038
 * Fixing some small perf issues with primitive protocol implementations.
 
# 2.037
 * Object constants work when explicitly specified via 'extend'.
 * Object arrays explicitly checked for protocol dispatch when 
   dealing with array types.
 * 'true' and 'false' supported as object constant types - nil unsupported.
 * Namespace comments.
 
# 2.036
 * Work on defprotocol to support primitive and constant return types.
 
# 2.035
 * Mutable treelists now result in less data on sublist and error on double persistent call.

# 2.034
 * Fix to smarter sublist impl - incorrect in some cases -- tests updated to catch in future.
 
# 2.033
 * MAJOR UPGRADE - implemented vec and vector as treelists.  This matches Clojure's
   persistent vector implementation in performance for mutable and immutable conj,
   reduce pathways but has a much smarter subvec implementation and faster
   conversion to and from object arrays.
 
# 2.032
 * Two merge-iterator implementations used to N-way merging of sorted sequences.  Linear is for small n <= 32 and
   the priority queue method is for larger N's.  The exact cutoff where performance will matter will depend on
   the dataset and the relative cost of the comparator.
 * Attempted to move all sorts to Arrays/parallelSort as it outperforms fastutils parallel sort by a bit.
 * added lsum, lsummary, dsummary for long-space sum, and simple summary statistics [min max mean sum n-elems] in long and double space respectively.

# 2.031
 * `(reduce + 0 (lznc/apply-concat nil))` works.

# 2.030
 * pmap-opts could produce an empty incorrect result if a custom pool was provided and parallelism was not specified.

# 2.029
 * Error in hash-map compute - did not remove key if compute fn was nil.

# 2.028
 * First class bloom filter support - uses apache parquet block-split-bloom-filter.

# 2.027
 * Fix for api/difference when left hand side is a java map.

# 2.026
 * Somewhat faster byte and short array creation when input is an IMutList impl.

# 2.025
 * Bugfix so update-values is consistent with persistent maps.

# 2.024
 * Bugfix for add-constant! default impls.

# 2.023
 * Bulk add-constant interface for all growable lists.

# 2.022
 * growable lists support clear.

# 2.021
 * `lines` - replacement for line-seq that returns an auto-closeable iterable and cannot cache nor hold-onto-head
    the data.
 * `re-matches` - faster version of re-matches.

# 2.020
 * split caffeine support off into its own namespace.

# 2.019
 * impl/pmap really does support user-defined thread pool.

# 2.018
 * Add clj-kondo exports and config, fix linting errors
 * Remove support for and call to `take-last` 1-arity, which was not valid.
 * Fix variable arity `merge-with`, which was not correctly implemented.
 * `apply-concat`, `concat-opts` accept cat-parallelism option allow you to specify how the concatenation
   should be parallelized at the creation source as opposed to at the preduce/parallel reduction callsite.

# 2.017
 * Faster compose-reducers especially where there really are a lot of reducers.

# 2.015
 * [issue 13](https://github.com/cnuernber/ham-fisted/issues/13) - any IMutList chunkedSeq was partially incorrect.

# 2.014
 * frequencies respects map-fn option to allow concurrent hashmaps to be used.

# 2.013
 * `cartesian-map` no longer has a random access variant.  The cooler version of this uses the tensor
   address mechanism to allow parallel redution.
 * fixed major issue with parallel frequencies.

# 2.011
 * Much faster every? implementation esp. for primitive arrays and persistent vectors.
 * More hlet extensions - `lng-fns` and `dbl-fns` which are faster in the general case
   then `lngs` and `dbls` as they avoid RT/nth.
 * efficient `cartesian-map` which does a cartesian join across its inputs and calls f on
   each value.
```clojure
user> (hamf/sum-fast (lznc/cartesian-map
                      #(h/let [[a b c d](lng-fns %)]
                         (-> (+ a b) (+ c) (+ d)))
                      [1 2 3]
                      [4 5 6]
                      [7 8 9]
                      [10 11 12 13 14]))
3645.0
```

# 2.010
 * Extensible let - hlet and helpers make using the primitive overloads of clojure functions easier.
   See the ham-fisted.hlet and ham-fisted.primtive-invoke namespaces.

# 2.009
 * typed 'nth' methods efficient for primitive manipulations - 'dnth', 'fnth', 'inth', 'lnth'.


# 2.008
 * Custom reduce implemented for object array wrappers.


2.007
* reduce namespace now has helper to create a parallel reducer.
* hashset has optimized addall pathway when input is another hashset.

# 2.006
 * partition-by accepts a predicate function in options - example in docs.

# 2.005
 * implemented lazy noncaching partition-all - similar perf to partition-by.
 * Faster default dispatch for pgroups, upgroups.
 * Faster sum-fast if input is random access.

# 2.004
 * Faster sort implemented as default in several places.

# 2.004
 * Ensure all object sorting is done with parallelQuickSort.
 * Small fix to array macros to use l2i instead of RT.intCast.

# 2.003
 * Major issue in compose-reducers - object composition was typed to double reduction.

# 2.002
 * slightly faster partition-by - inner loop written in java.

# 2.001
 * Added lazy-noncaching partition-by.  This method has somewhat higher performance than
   clojure.core/partition-by as it does not make intermediate containers and is strictly
   lazy-noncaching.

# 2.000
 * Rebuilt hashmaps on faster foundation especially for micro benchmarks.
 * Removed bits and pieces that do not provide enough return on investment.
 * For more in-depth comments see [PR-7](https://github.com/cnuernber/ham-fisted/pull/7).

# 1.009
 * new linked hashmap implementation with equiv-semantics and fast union op.

# 1.008
 * Fast set intersection for longer sequencers of sets (intersect-sets).

# 1.007
 * Fast pathways for finding min/max index of a collection of objects in a similar way to min-key and max-key.

# 1.006
 * Very specific upgrade to combine-reducers pathways.

# 1.005
 * pmap, upmap pathways now return an object that full implements seqable and ireduceinit.

# 1.002
 * Added n-lookahead to the parallel options pathway as for some problems
   this makes a major difference in the efficiency of the pmap pathway.

# 1.001
 * Fixed pmap implementation to release memory much more aggressively.

# 1.000-beta-98
 * Fixed serious but subtle issue when a transient hash map is resized.  This should be
   considered a must-have upgrade.

# 1.000-beta-96
 * Fixed from upgrading dtype-next.
 * Major breaking changes!! API functions have been moved to make the documentation
   clearer and the library more maintainable in the long run.
 * map-union of mutable or transient maps produces mutable or transient maps!
 * Final refactoring before 1.000 release.
 * Functions to make creating java.util.function objects are moved to ham-fisted.function.
 * Reduction-related systems are moved to ham-fisted.reduce.
 * java.util.Map helpers are moved to ham-fisted.mut-map.

# 1.000-beta-93
 * java implementation of a batched stream reducer.  This avoids adding java to
   the stream api.

# 1.000-beta-92
 * pure java reductions for situations where you have an index fn a count.  These mainly
   just make benchmarks a bit more stable.

# 1.000-beta-91
 * IFnDef supports interfaces for long supplier (L), double supplier (D), and
   Supplier (O).

# 1.000-beta-90
 * Accelerated map boolean union, intersection, difference  for hashtable, long hashtable.
 * Major bugfix in map dissoc.


# 1.000-beta-89
 * Added inc-consumer - returns a generic consumer that increments a long.  Useful for the various
   situations where you need to track an incrementing variable but don't want the overhead of
   using a volatile variable.

# 1.000-beta-88
 * Immutable maps and vectors derive from APersistentMap and APersistentVector so that downtream
   libraries can pick them up transparently.

# 1.000-beta-86
 * Error in reduction of empty ranges.

# 1.000-beta-85
 * Slightly faster map construction pathways.
 * In fact both the hamf base map `mut-map` and the integer-specialized `mut-long-hashtable-map` are
   faster than the default `clojure.data.int-map` pathway for construction and value lookup according
   to the benchmarks in `clojure.data.int-map`.  Interestingly enough they are fastest if you create
   an intermediate object array using lznc/apply-concat:

```clojure
user> (count entries)
1000000
user> (c/quick-bench (into (persistent! (hamf/mut-long-hashtable-map))  entries))
Evaluation count : 6 in 6 samples of 1 calls.
             Execution time mean : 366.247830 ms
    Execution time std-deviation : 11.024896 ms
   Execution time lower quantile : 348.564420 ms ( 2.5%)
   Execution time upper quantile : 376.625750 ms (97.5%)
                   Overhead used : 1.492920 ns
nil
user> (c/quick-bench (into (i/int-map) entries))
Evaluation count : 6 in 6 samples of 1 calls.
             Execution time mean : 568.189038 ms
    Execution time std-deviation : 1.677163 ms
   Execution time lower quantile : 566.564884 ms ( 2.5%)
   Execution time upper quantile : 570.564253 ms (97.5%)
                   Overhead used : 1.492920 ns
nil
user> (def ll (into (persistent! (hamf/mut-long-hashtable-map)) entries))
#'user/ll
user> (def il (into (i/int-map) entries))
#'user/il
user> (c/quick-bench
       (dotimes [idx (count entries)]
         (.get ^java.util.Map ll idx)))

Evaluation count : 84 in 6 samples of 14 calls.
             Execution time mean : 7.399383 ms
    Execution time std-deviation : 62.314286 µs
   Execution time lower quantile : 7.297162 ms ( 2.5%)
   Execution time upper quantile : 7.451677 ms (97.5%)
                   Overhead used : 1.492920 ns
nil
user> (c/quick-bench
       (dotimes [idx (count entries)]
         (.get ^java.util.Map il idx)))

Evaluation count : 30 in 6 samples of 5 calls.
             Execution time mean : 22.936125 ms
    Execution time std-deviation : 583.510734 µs
   Execution time lower quantile : 22.334216 ms ( 2.5%)
   Execution time upper quantile : 23.654541 ms (97.5%)
                   Overhead used : 1.492920 ns
nil
user>

user> (c/quick-bench (hamf/mut-long-hashtable-map (hamf/into-array Object (lznc/apply-concat entries))))
Evaluation count : 6 in 6 samples of 1 calls.
             Execution time mean : 271.755568 ms
    Execution time std-deviation : 1.545379 ms
   Execution time lower quantile : 270.184413 ms ( 2.5%)
   Execution time upper quantile : 273.736344 ms (97.5%)
                   Overhead used : 1.492920 ns
nil
```


# 1.000-beta-84
 * `wrap-array`, `wrap-array-growable`, major into-array optimizations and better
   `map-reducible`.

# 1.000-beta-83
 * Opening the door to custom IReduce implementations.

# 1.000-beta-82
 * convert hashsets to use hashtables instead of bitmap tries.
 * careful analysis of various vec-like object creation mechanisms.

# 1.000-beta-81
 * long primitive hashtables - these are quite a bit faster but especially when used directly.

# 1.000-beta-80
 * Helpers for very high performance scenarios.  lazy-noncaching/map-reducible,
   api/->long-predicate.

# 1.000-beta-78
 * fill-range is now property accelerated making all downstream projects that use addAll and
   friends far faster.

# 1.000-beta-77
 * see [commit 38596d8](https://github.com/cnuernber/ham-fisted/commit/38596d85541de7d2c926ac8b16522a764fcb6af9)

# 1.000-beta-76
 * Added group-by-consumer - this has different performance and functionality characteristics
   than group-by-reducer.  For instance, group-by-consumer with a linked hashmap will return
   a map with keys in the order of keys initially encounted.  group-by-reducer with the same
   hashmap will return a map with keys in the order of latest encountered.  Group-by-consumer
   uses `computeIfAbsent` which is a slightly faster primitive than `compute` as it doesn't
   need to check the return value of the reducer, only of the initialization of the map
   entry.

# 1.000-beta-75
 * MapForward class so we can use normal java maps in normal Clojure workflows.

# 1.000-beta-74
 * bugfix - Map's `compute` has to accept nil keys.

# 1.000-beta-73
 * memoize now supports `:eviction-fn` - for callbacks when things get evicted.
 * More helpers for memoized fns - cache-as-map, evict-memoized-call.

# 1.000-beta-72
 * Switch to caffeine for memoize cache and standard java library priority queue for take-min.
 This removed the dependency on google guava thus drastically cutting the chances for dependency
 conflicts.

# 1.000-beta-71
 * HUGE CHANGES!!! - moved to hashtable implementation for main non-array map instead of
   bitmap trie.  This is because in all my tests it is *much* faster for everything *aside*
   from non-transient (reduce assoc ...) type loops which are a waste of time to begin with.
 * Because there are now three full map implementations  (array, trie, hashtable) there is a
   more defined map structure making it less error prone to test out different map backends.
 * Lots of inner class renaming and such - however `frequencies`, `group-by-reduce`, and
   `mapmap` now a bit faster - about 2X.  Here is a telling performance metric:

```clojure
({:construct-μs 2.726739663709692,
  :access-μs 1.784634592104282,
  :iterate-μs 2.7345543552812073,
  :ds-name :java-hashmap}
 {:construct-μs 3.5414584143710885,
  :access-μs 2.761234751112207,
  :iterate-μs 2.1730894775185403,
  :ds-name :hamf-hashmap}
 {:construct-μs 6.475808180747403,
  :access-μs 2.484804237281106,
  :iterate-μs 1.8564705765641765,
  :ds-name :hamf-transient}
 {:construct-μs 11.43649782981362,
  :access-μs 5.152473242630386,
  :iterate-μs 8.793332955848225,
  :ds-name :clj-transient})
ham-fisted.hash-map-test>
```


# 1.000-beta-69
 * Faster `mode`.
 * Faster map iteration.
 * Corrected clojure persistent hash map iteration.

# 1.000-beta-67
 * Faster `mode`.
 * `mmax-key` - use `(mmax-key f data)` as opposed to `(apply max-key f data)`.  It is faster
   and handles empty sequences.  Same goes for `mmin-key`.


# 1.000-beta-66
 * Fixed `make-comparator`.
 * Added `mode`.

# 1.000-beta-65
 * Better obj->long and obj->double pathways that will always apply the appropriate cast
   and thus have 0 arg variants.
 * Better/faster sort-by pathway that avoids potential intermediate data creation.

# 1.000-beta-64
 * Fixed predicate, long-consumer, double-consumer and consumer pathways.
 * Faster dispatch for preduce.

# 1.000-beta-62
 * Faster dispatch for preduce.

# 1.000-beta-61
 * All lists are comparable.

# 1.000-beta-60
 * nil is convertible to iterable and collections without fail.

# 1.000-beta-59
 * Container reduction must respect reduced - I think this is a design flaw but not a
 serious or impactful one aside from requiring more complex per-container reduction code.

# 1.000-beta-58
 * Perf tweaks and small fixes from TMD.

# 1.000-beta-57
 * Additional round of optimizations around creation of persistent vector objects.
 * renamed a few of the functor-creation macros.
 * lznc/map explicity supports long->obj transformations as these are often used as
   index->obj lookup systems.
 * Rebuilt IMutList's toArray pathway to use reduction.

# 1.000-beta-56
 * Switched completely to clojure.core.protocols/CollReduce.
 * Removed a solid amount of cruft and simplified reduction architecture.
 * Now loading hamf transparently makes reductions on all arrays and many
   java such as hashmaps datastructures faster.


# 1.000-beta-55
 * Removed lots of old cruft.
 * Added IFnDef predicates so you can use IFn-based predicates from java.

# 1.000-beta-54
 * Removed lots of old cruft.
 * Added IFnDef predicates so you can use IFn-based predicates from java.

# 1.000-beta-53
 * `:unmerged-result?`, `:skip-finalize?` options for `preduce` and `preduce-reducer`.  This
   allows you to use the parallelized reductions pathway but get a sequence of results back
   as opposed to a single result.  It also allows you to used reducers or
   transducing-compatible rfn's that have no parallel merge pathway and handle the parallel
   merge yourself after the parallelized reduction.
 * Fixed issue with single-map parallel reductions to ensure that it passes the parallel
   reduction request to its source data.

# 1.000-beta-52
 * bulk union, intersection operations.
 * Faster `equiv` for longs and doubles but equivalent for everything else.

# 1.000-beta-51
 * additional set operation - parallelized `unique`.
 * exposed indexed accumulator macros in api for use outside library.
 * generic protocol fn add-fn that must return a reduction compatible function
   for a given collection.

# 1.000-beta-50
 * forgot type hints on array constructors.

# 1.000-beta-49
 * Final round of optimizations for double array creation.  Turns out reductions really
   are faster.

# 1.000-beta-48
 * macros for double, float, long, and int array creation that will inline a fastpath
   if the argument is a compile-time vector or integer.  Bugfix for casting floats
   to longs.
 * shorthand macros, ivec, lvec, fvec, dvec to create array-backed containers that
   allow nth destructuring.

# 1.000-beta-47
 * major double-array, float-array, long-array, int-array optimizations.

# 1.000-beta-46
 * Set protocol to supercede the set protocol from dtype-next.
 * lots and lots of fixes from dataset work.

# 1.000-beta-45
 * Small fixes and making helpers public for dtype-next work.

# 1.000-beta-43
 * long lists really are long lists - copy-paste mistake from int lists.

# 1.000-beta-42
 * declare-double-consumer-preducer! - given type derived from DoubleConsumer
   and a few others, create a parallel reducer.
 * declare-consumer-preducer! - similar to above, incoming data is not expected
   to be a stream of double values.

# 1.000-beta-41
 * ->collection is protocol driven allowing new non-collection things like bitmaps
   to be turned temporarily into collections.  This means that reductions and collection
   conversion are protocol driven.

# 1.000-beta-40
 * maps are iterable...

# 1.000-beta-39
 * Explicit protocols for serial and parallel reduction and reducers.
 * Explicit support for BitSet objects.
 * Updated (->reducible) pathways to check for protocol reducer support.
 * Protocol for conversion of arbitrary types to iterable for map, filter support.

# 1.000-beta-38
 * Fixed comparison of seq with nonseq.

# 1.000-beta-37
 * Small perf enhancements from tmd perf regression

# 1.000-beta-36
 * Added in explicit checks for long, double, and predicate objects in filter's reduction
   specializations.  Potentially these are too expensive but it does help a bit with
   longer sequences.
 * Changed things such that Double/NaN evaluates to false.  This matches that the null
   object evaluates to false and null evaluates to Double/NaN.


# 1.000-beta-35
 * Added finalize method to reducers to match transducer spec.
 * Exposed `compose-reducers` that produces a new reducer from a map or sequence of
   other reducers.
 * These changes simplfied `reduce-reducers` and `preduce-reducers`, `sum` and `sum-fast`.


# 1.000-beta-34
 * Enable parallelization for instances of clojure.core.PersistentHashMap.
 * protocol-based parallelization of reductions so you can extend the parallelization
   to new undiscovered classes.
 * reducer-xform->reducer - Given a reducer and a transducer xform produce a new reducer
   that will apply the transform to the reduction function of the reducer:

```clojure
ham-fisted.api> (reduce-reducer (reducer-xform->reducer (Sum.) (clojure.core/filter even?))
                                (range 1000))
#<Sum@70149930: {:sum 249500.0, :n-elems 500}>
```

# 1.000-beta-33
 * Finally a better api to group-by-reduce and group-by can now be implemented
   via group-by-reduce.  group-by-reduce uses same 3 function arguments as
   preduce so your reduction systems are interchangable between these two
   systems.
 * Fixed `conj` for all growable array lists.
 * Added a protocol for parallel reductions.  This allows you to pass in one object
   and transform it into the three functions required to do a parallel reduction.
 * Added preduce-reducer, preduce-reducers for a single reducer or a sequence or
   map of reducers, respectively.


# 1.000-beta-32
 * group-by, group-by-reduced fixed for large n.

# 1.000-beta-31
 * min-n is now a long with parallel options.
 * lazy-noncaching namespace now has map-indexed.  Faster reductions and random access
   objects stay random access.

# 1.000-beta-30
 * Various bugfixes from dtype work.

# 1.000-beta-29
 * Ranges with more than Integer/MAX_VALUE elems can be accessed via their IFn overloads
  and support custom lgetLong and lgetDouble methods that take long indexes for long and
  double ranges.


# 1.000-beta-28
 * Use lookahead and put timeouts for all parallelization primitives so that if a long
  running parallelization is cancelled the forkjoin pool itself isn't hung.
 * Enable long and double ranges whose size is larger than Integer/MAX_VALUE.  This includes
   parallelized reductions which even optimized take basically forever.
 * Add better defaults for reductions to long and double -specific IMutList interfaces.
 * Ensure reduction implementations do not dereference a reduced accumulator.
 * Fix reducible interface to it matches preduce.
 * Added persistent! implementation which fails gracefully if input is already persistent.
 * Fixed group-by, group-by-reduce, and pfrequencies implementation to use preduce.
 * conj works on map, filter, and concat from the lazy-noncaching library.

# 1.000-beta-27
 * Remove explicit support for boolean primitives.

# 1.000-beta-26
 * IFnDef overloads implement their appropriate java.util.function counterparts.

# 1.000-beta-25
 * Removed claypoole from dependencies.
 * Move typed clojure function interface definitions from Reductions to IFnDef.
 * Added overrides of keys, vals that produce parallelizable collections if the input
   itself is a parallelizable collection - either maps from this library or any java
   hashmap.

# 1.000-beta-24
 * preduce has new option to help parallelize concat operations - they can be parallelized
   two different ways, either elemwise where each container parallelizes its reduction or
   by sequence where an initial reduction is done with pmap then the results are merged.
 * all random access contains support spliterator and typed stream construction.
 * Fix bug in upmap causing hanging with short sequences.

# 1.000-beta-23
 * double conversion to long fails for NaN.
 * Careful combining of typed map/filter chains to avoid causing inaccuracies when
   converting from double to long.
 * Major parallelism upgrade - spliterator-based objects such as java.util.hashmap and
   all the hashmaps/hashsets from this library now support parallelized reduction.

# 1.000-beta-22
 * Numeric values are range checked on input to addLong.

# 1.000-beta-21
 * Removed ensureCapacity from IMutList.

# 1.000-beta-20
 * Moved to double reduction as opposed to double foreach.  Perftested heavily and found that reduce
   is just as fast and more general.

# 1.000-beta-18
 * expose sublistcheck.

# 1.000-beta-17
 * Stricter correctness checking for sublist types, everything implements Associative.

# 1.000-beta-16
 * Correctness fixes for pmap, upmap, pgroups, upgroups.

# 1.000-beta-15
 * Fixed sum for large n-elems.
 * upgroups - Unordered parallel groupings for random access systems.
 * Indexed consumers for copying, broadcasting type operations.
 * Reducible interface for objects that can reduce themselves.

# 1.000-beta-14
 * ArraySection is now first-class, will rebase dtype-next array pathways on this.

# 1.000-beta-12
 * pmap is guaranteed *not* to require `shutdown-agents`.


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright © 2021 Chris Nuernberger

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

================================================
FILE: README.md
================================================
# HAM-Fisted

[![Clojars Project](https://clojars.org/com.cnuernber/ham-fisted/latest-version.svg)](https://clojars.org/com.cnuernber/ham-fisted)
* [API docs](https://cnuernber.github.io/ham-fisted/)
* [Clojure Conj Talk](https://www.youtube.com/watch?v=ralZ4j_ruVg)

## Summary

Clojure-style immutable collections (and mutable counterparts), together with
some operations, all aimed at high performance.

In particular, high-performance in large-`n` and parallel contexts. Included are
a namespace of lazy but not caching operations, a `ForkJoinPool` oriented
`pmap`, and a system of parallel reductions. This gives the user
somewhat-drop-in replacements for familiar Clojure tools that can be faster.

## History

What started as a collection of efficient mutable and immutable data structures based
on Phil Bagwell's bitmap trie concept became an overall reimplementation of
Clojure's core datastructures and some of its base concepts specifically with
performance in mind.  This means, for instance, that the library prefers iterators
over sequences in many situations.  There are also new functional primitives developed
from my experience processing data and working with Clojure over the last 10 years.


My hope is this library becomes a platform to experiment and develop new and/or better
functional datastructures and algorithmic primitives.


Here are a few concepts to keep in mind -


## In-place Mutable -> Persistent

The mutable hashmap and vector implementations allow in-place instantaneous conversion to
their persistent counterparts.  This allows you to build a dataset using the sometimes much
faster mutable primitives (.compute and friends for instance in the hashmap case) and then
return data to the rest of the program in persistent form.  Using this method, for example
`frequencies` is quite a bit faster while still returning a persistent datastructure.


Along those lines construction of a persistent vector from an object array is very fast
so it is very efficient to construct a persistent vector from an object-array-list - the
array list being much faster to build.


## New Primitive Operations

There are many new primitive operations than listed below - please take a moment to scan
the api docs.  Some standouts are:

#### Map Union, Difference, Intersection

Aside from simply a reimplementation of hashmaps and persistent vectors this library
also introduces a few new algorithms namely map-union, map-intersection, and
map-difference.  These are implemented at the trie level so they avoid rehashing any
keys and use the structure of the hashmap in order to boost performance.  This means
`merge` and `merge-with` are much faster especially if you have larger maps.  But it
also means you can design novel set-boolean operations as you provide a
value-resolution operator for the map values.


Because the hamf hashmaps have fast unions, you can now design systems where for
instance each thread builds up a separate hashmap and the results are unioned together
back in the main thread in a map-reduce type design.  This type of design was the
original target of the union system.

These systems are substantially faster if the objects have a high cost to hash and do
not cache their hashcode but  this is rare for Clojure systems as persistent vectors, maps
and keywords cache their hash values.  Strings, however, are an example of something where
these primitives (and things like frequencies) will perform substantially better.


### Casting and Finite Numbers

Float and double values are only allowed to cast to long if they are
[finite](https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#isFinite-double-).
Boolean values casted to long or double are 0 for false and 1 for true.  Any nonzero
finite number casted to boolean is true, 0 is false, non-finite numbers are errors.  `nil`
casted to a floating point number is NaN.  NaN casted to an object is NaN.  If objects
are not number then nil is false and non-nil is true.  Any undefined cast falls back to
`clojure.lang.RT.xCast` where `x` denotes the target type.


Reading data from contains leads to unchecked casts while writing data to contains
leads to checked casts.



#### update-values, group-by-reduce, mapmap

* `update-vals` - is far faster than map->map pathways if you want to update every
  value in the map but leave the keys unchanged.
* `group-by-reduce` - perform a reduction during the group-by.  This avoids keeping
   a large map of the complete intermediate values which can be both faster and more
   memory efficient.
* `mapmap` - A techascent favorite, equivalent to:
```clojure
(->> (map map-fn src-map) (remove nil?) (into {}))
```

#### Parallelized Reductions - preduce


I have an entire topic on [Reductions](https://cnuernber.github.io/ham-fisted/Reductions.html) -
give it a read and then send me an email with your thoughts :-).

* [preduce](https://cnuernber.github.io/ham-fisted/ham-fisted.api.html#var-preduce)
* [preduce-reducer](https://cnuernber.github.io/ham-fisted/ham-fisted.api.html#var-preduce-reducer)
* [preduce-reducers](https://cnuernber.github.io/ham-fisted/ham-fisted.api.html#var-preduce-reducers)


These parallelization primitives allow users to pass in their own forkjoin pools
so you can use it for blocking tasks although it is setup be default for
cpu-bound operations.  Concat operations can parallelize reductions over
non-finite or non-parallelizable containers using the default `:seq-wise`
`:cat-parallelization` option.


#### All Arrays Are First Class

* Any array including any primitive array can be converted to an indexed operator
 with efficient sort, reduce, etc. implementations using the `lazy-noncaching`
 namespace's `->random-access` operator.  This allows you to pass arrays as is to
 the rest of your clojure program without conversion to a persistent vector -
 something that is both not particularly efficient and explodes the data size.


#### Random Access Containers Support Negative Indexes

All random access containers, be it vectors, lists, or array lists support
nth, ifn interfaces taking -1 to index from the end of the vector.  For performance
reasons, the implementation of List.get does not -

```clojure
ham-fisted.persistent-vector-test> ((api/vec (range 10)) -1)
9
ham-fisted.persistent-vector-test> (nth (api/vec (range 10)) -1)
9
ham-fisted.persistent-vector-test> (.get (api/vec (range 10)) -1)
Execution error (IndexOutOfBoundsException) at ham_fisted.ChunkedList/indexCheck (ChunkedList.java:210).
Index underflow: -1
ham-fisted.persistent-vector-test> ((api/->random-access (api/int-array (range 10))) -1)
9
ham-fisted.persistent-vector-test> (nth (api/->random-access (api/int-array (range 10))) -1)
9
```
Similarly `last` is constant time for all any list implementation deriving from
`java.util.RandomAccess`.

## Other ideas

 * `lazy-noncaching` namespace contains very efficient implementations of map,
   filter, concat, and repeatedly which perform as good as or better than the
   eduction variants without chunking or requiring you to convert your code from
   naive clojure to transducer form.  The drawback is they are lazy noncaching so
   for instance `(repeatedly 10 rand)` will produce 10 random values every time it
   is evaluated.  Furthermore `map` will produce a random-access return value if
   passed in all random-access inputs thus preserving the random-access property of
   the input.

 * lazy-caching namespace contains inefficient implementations that do in fact
   cache - it appears that Clojure's base implementation is very good or at least
   good enough I can't haven't come up with one better.  Potentially the decision
   to use chunking is the best optimization available here.


## Contributing

The best way to contribute is to fund me through github sponsors linked to
the right or to engage [TechAscent](https://techascent.com) - we are always
looking for new interesting projects and partners.


Aside from that as mentioned earlier my hope is this library becomes
a platform that enables experimentation with various functional primitives and
overall optimized ways of doing the type of programming that the Clojure community
enjoys.  Don't hesitate to file issues and PR's - I am happy to accept both.

If you want to work on the library you need to enable the `:dev` alias.


## Benchmarks

Lies, damn lies, and benchmarks - you can run the benchmarks with `./scripts/benchmark`.
Results will be printed to the console and saved to results directory prefixed by the
commit, your machine name and the jdk version.

Results will print normalized to either the base time for clojure.core (clj) or for
java.util (java).  One interesting thing here is in general how much better JDK-17
is for many of these tests than JDK-8.

Here are some example timings taken using my laptop plugged in with an external cooling
supply (frozen peas) applied to the bottom of the machine.  An interesting side note is
that I get better timings often when running from the REPL for specific benchmarks than
from the benchmark - perhaps due to the machine's heat management systems.


#### JDK-17


|                  :test | :n-elems | :java | :clj | :eduction | :hamf | :norm-factor-μs |
|------------------------|---------:|------:|-----:|----------:|------:|----------------:|
|              :assoc-in |        5 |       |  1.0 |           | 0.646 |           0.245 |
|          :assoc-in-nil |        5 |       |  1.0 |           | 0.371 |           0.120 |
|               :concatv |      100 |       |  1.0 |           | 0.099 |           9.827 |
|           :frequencies |    10000 |       |  1.0 |           | 0.412 |         966.154 |
|                :get-in |        5 |       |  1.0 |           | 0.564 |           0.124 |
|              :group-by |    10000 |       |  1.0 |           | 0.333 |        1414.480 |
|       :group-by-reduce |    10000 |       |  1.0 |           | 0.313 |        1408.028 |
|        :hashmap-access |    10000 | 0.700 |  1.0 |           | 0.989 |         549.468 |
|        :hashmap-access |       10 | 0.837 |  1.0 |           | 0.826 |           0.400 |
|  :hashmap-cons-obj-ary |        4 |       |  1.0 |           | 0.355 |           0.392 |
|  :hashmap-cons-obj-ary |       10 |       |  1.0 |           | 0.584 |           0.864 |
|  :hashmap-cons-obj-ary |     1000 |       |  1.0 |           | 0.541 |         124.811 |
|  :hashmap-construction |    10000 | 0.563 |  1.0 |           | 0.923 |        1331.130 |
|  :hashmap-construction |       10 | 0.240 |  1.0 |           | 0.357 |           2.337 |
|        :hashmap-reduce |    10000 | 0.792 |  1.0 |           | 0.860 |         316.433 |
|        :hashmap-reduce |       10 | 0.703 |  1.0 |           | 0.735 |           0.360 |
|              :int-list |    20000 | 1.000 |      |           | 1.147 |         467.994 |
|                :mapmap |     1000 |       |  1.0 |           | 0.276 |         275.786 |
|          :object-array |    20000 |       |  1.0 |           | 0.240 |        1560.975 |
|           :object-list |    20000 | 1.000 |      |           | 0.987 |         518.878 |
|    :sequence-summation |    20000 |       |  1.0 |      0.29 | 0.409 |        1380.496 |
|               :shuffle |    10000 |       |  1.0 |           | 0.353 |         329.709 |
|                  :sort |    10000 |       |  1.0 |           | 0.337 |        2418.307 |
|          :sort-doubles |    10000 |       |  1.0 |           | 0.374 |        2272.143 |
|             :sort-ints |    10000 |       |  1.0 |           | 0.291 |        2514.779 |
|                 :union |       10 | 0.155 |  1.0 |           | 0.088 |           1.785 |
|                 :union |    10000 | 0.275 |  1.0 |           | 0.174 |        1664.823 |
|            :union-disj |       10 | 0.156 |  1.0 |           | 0.085 |           1.798 |
|            :union-disj |    10000 | 0.279 |  1.0 |           | 0.178 |        1641.344 |
|          :union-reduce |       10 | 0.139 |  1.0 |           | 0.220 |          23.954 |
|          :union-reduce |    10000 | 0.100 |  1.0 |           | 0.159 |       41261.663 |
|             :update-in |        5 |       |  1.0 |           | 1.153 |           0.276 |
|         :update-in-nil |        5 |       |  1.0 |           | 0.276 |           0.158 |
|         :update-values |     1000 |       |  1.0 |           | 0.090 |         158.994 |
|         :vector-access |       10 | 1.568 |  1.0 |           | 1.008 |          77.945 |
|         :vector-access |    10000 | 0.957 |  1.0 |           | 1.027 |         125.778 |
| :vector-cons-obj-array |       10 | 1.184 |  1.0 |           | 0.356 |           0.071 |
| :vector-cons-obj-array |    10000 | 0.083 |  1.0 |           | 0.048 |         112.192 |
|   :vector-construction |       10 | 0.460 |  1.0 |           | 1.124 |           0.078 |
|   :vector-construction |    10000 | 0.082 |  1.0 |           | 0.078 |         117.432 |
|         :vector-reduce |       10 | 1.996 |  1.0 |           | 1.088 |           0.150 |
|         :vector-reduce |    10000 | 1.228 |  1.0 |           | 0.863 |         194.194 |
|       :vector-to-array |       10 | 0.256 |  1.0 |           | 0.503 |           0.041 |
|       :vector-to-array |    10000 | 0.063 |  1.0 |           | 0.124 |          69.590 |


#### JDK-1.8


|                  :test | :n-elems | :java | :clj | :eduction | :hamf | :norm-factor-μs |
|------------------------|---------:|------:|-----:|----------:|------:|----------------:|
|              :assoc-in |        5 |       |  1.0 |           | 0.801 |           0.274 |
|          :assoc-in-nil |        5 |       |  1.0 |           | 0.275 |           0.142 |
|               :concatv |      100 |       |  1.0 |           | 0.120 |           6.810 |
|           :frequencies |    10000 |       |  1.0 |           | 0.421 |         960.710 |
|                :get-in |        5 |       |  1.0 |           | 0.598 |           0.125 |
|              :group-by |    10000 |       |  1.0 |           | 0.335 |        1410.690 |
|       :group-by-reduce |    10000 |       |  1.0 |           | 0.293 |        1433.528 |
|        :hashmap-access |    10000 | 0.817 |  1.0 |           | 1.046 |         541.540 |
|        :hashmap-access |       10 | 0.791 |  1.0 |           | 0.904 |           0.402 |
|  :hashmap-cons-obj-ary |        4 |       |  1.0 |           | 0.398 |           0.407 |
|  :hashmap-cons-obj-ary |       10 |       |  1.0 |           | 0.696 |           0.682 |
|  :hashmap-cons-obj-ary |     1000 |       |  1.0 |           | 0.449 |         130.423 |
|  :hashmap-construction |    10000 | 0.586 |  1.0 |           | 0.927 |        1281.371 |
|  :hashmap-construction |       10 | 0.278 |  1.0 |           | 0.401 |           2.238 |
|        :hashmap-reduce |    10000 | 0.625 |  1.0 |           | 0.704 |         321.295 |
|        :hashmap-reduce |       10 | 0.714 |  1.0 |           | 0.862 |           0.312 |
|              :int-list |    20000 | 1.000 |      |           | 1.017 |         497.492 |
|                :mapmap |     1000 |       |  1.0 |           | 0.325 |         226.518 |
|          :object-array |    20000 |       |  1.0 |           | 0.391 |        1374.725 |
|           :object-list |    20000 | 1.000 |      |           | 0.981 |         493.795 |
|    :sequence-summation |    20000 |       |  1.0 |      0.37 | 0.227 |        1342.562 |
|               :shuffle |    10000 |       |  1.0 |           | 0.430 |         286.478 |
|                  :sort |    10000 |       |  1.0 |           | 0.284 |        2839.552 |
|          :sort-doubles |    10000 |       |  1.0 |           | 0.424 |        2485.058 |
|             :sort-ints |    10000 |       |  1.0 |           | 0.279 |        2885.107 |
|                 :union |       10 | 0.147 |  1.0 |           | 0.093 |           1.938 |
|                 :union |    10000 | 0.278 |  1.0 |           | 0.198 |        1446.922 |
|            :union-disj |       10 | 0.144 |  1.0 |           | 0.091 |           1.938 |
|            :union-disj |    10000 | 0.285 |  1.0 |           | 0.198 |        1440.777 |
|          :union-reduce |       10 | 0.114 |  1.0 |           | 0.230 |          25.724 |
|          :union-reduce |    10000 | 0.081 |  1.0 |           | 0.159 |       37008.010 |
|             :update-in |        5 |       |  1.0 |           | 1.401 |           0.292 |
|         :update-in-nil |        5 |       |  1.0 |           | 0.289 |           0.138 |
|         :update-values |     1000 |       |  1.0 |           | 0.083 |         166.794 |
|         :vector-access |       10 | 1.563 |  1.0 |           | 1.131 |          86.023 |
|         :vector-access |    10000 | 0.945 |  1.0 |           | 1.047 |         139.996 |
| :vector-cons-obj-array |       10 | 1.150 |  1.0 |           | 0.365 |           0.075 |
| :vector-cons-obj-array |    10000 | 0.066 |  1.0 |           | 0.040 |         103.369 |
|   :vector-construction |       10 | 0.508 |  1.0 |           | 1.119 |           0.073 |
|   :vector-construction |    10000 | 0.062 |  1.0 |           | 0.070 |         109.040 |
|         :vector-reduce |       10 | 2.041 |  1.0 |           | 1.031 |           0.152 |
|         :vector-reduce |    10000 | 1.392 |  1.0 |           | 1.026 |         146.636 |
|       :vector-to-array |       10 | 0.284 |  1.0 |           | 0.569 |           0.036 |
|       :vector-to-array |    10000 | 0.052 |  1.0 |           | 0.068 |          65.946 |


## CAVEATS!!

This code is minimally tested.  The datastructures especially need serious testing, potentially generative
testing of edge cases.

Also, microbenchmarks do not always indicate how your system will perform overall.  For instance- when
testing `assoc-in`, `update-in` in this project we see better performance.  In at least one real
world project, however, the inlining that makes the microbenchmark perform better definitely did
*not* result in the project running faster -- it ran a bit slower even though the profiler of the
original code indicated the sequence operations performed during assoc-in and update-in were a source
of some time.

The JVM is a complicated machine and there are issues with using, for instance, too many classes
at a particular callsite.  Overall I would recommend profiling and being careful.  My honest opinion
right now is that `assoc-in` and `update-in` do not improve program performance at least in
some of the use cases I have tested.


## Other Interesting Projects

* [clj-fast](https://github.com/bsless/clj-fast) - Great and important library more focused on compiler upgrades.
* [bifurcan](https://github.com/lacuna/bifurcan) - High speed functional datastructures for Java.  Perhaps ham-fisted should
be based on this or we should measure the differences and take the good parts.
* [Clojure Goes Fast](http://clojure-goes-fast.com/) - Grandaddy aggregator project with a lot of important information and a set of crucial github projects such as [clj-memory-meter](https://github.com/clojure-goes-fast/clj-memory-meter).


================================================
FILE: build.clj
================================================
(ns build
  (:require [clojure.tools.build.api :as b]
            [clojure.edn :as edn])
  (:refer-clojure :exclude [compile]))

(def deps-data (edn/read-string (slurp "deps.edn")))
(def codox-data (get-in deps-data [:aliases :codox :exec-args]))
(def lib (symbol (codox-data :group-id) (codox-data :artifact-id)))
(def version (codox-data :version))
(def class-dir "target/classes")
(def basis (b/create-basis {:project "deps.edn"}))
(def jar-file (format "target/%s.jar" (name lib)))
(def uber-file (format "target/uber-%s.jar" (name lib)))

(defn clean [_]
  (b/delete {:path "target"}))

(defn compile [_]
  (b/javac {:src-dirs ["java"]
            :class-dir class-dir
            :basis basis
            :javac-opts ["-source" "8" "-target" "8" "-Xlint:unchecked"
                         ]}))

(def pom-template
  [[:licenses
    [:license
     [:name "MIT License"]
     [:url "https://github.com/cnuernber/charred/blob/master/LICENSE"]]]])


(defn jar [_]
  (compile nil)
  (b/write-pom {:class-dir class-dir
                :lib lib
                :version version
                :basis basis
                :src-dirs ["src"]
                :pom-data pom-template})
  (b/copy-dir {:src-dirs ["src" "resources"]
               :target-dir class-dir})
  (b/jar {:class-dir class-dir
          :jar-file jar-file}))


(defn perftest [_]
  (let [basis (b/create-basis {:aliases [:dev]})]
    (clean nil)
    (compile nil)
    (b/copy-dir {:src-dirs ["src" "dev/resources" "dev/src"]
                 :target-dir class-dir})
    (b/compile-clj {:basis basis
                    :src-dirs ["dev/src"]
                    :class-dir class-dir
                    :compile-opts {:direct-linking true}
                    })
    (b/uber {:class-dir class-dir
             :uber-file uber-file
             :basis basis
             :main 'ham-fisted.protocol-perf})))


================================================
FILE: codegen/gen_prim_invoke.clj
================================================
(ns gen-prim-invoke
  (:require [clojure.java.io :as io]
            [ham-fisted.lazy-noncaching :as lznc]
            [ham-fisted.api :as hamf]))


(defn single-arg-sigs
  [rv]
  (for [arg1 [:o :l :d]]
    [arg1 rv]))

(defn dual-arg-sigs
  [rv arg1]
  (for [arg2 [:o :l :d]]
    [arg1 arg2 rv]))


(defn triple-arg-sigs
  [rv arg1 arg2]
  (for [arg3 [:o :l :d]]
    [arg1 arg2 arg3 rv]))


(defn quad-arg-sigs
  [rv arg1 arg2 arg3]
  (for [arg4 [:o :l :d]]
    [arg1 arg2 arg3 arg4 rv]))



(def ifn-sigs
  (hamf/concatv
   [[:l]
    [:d]]
   (->> (lznc/concat
         (for [rv [:o :l :d]]
           (single-arg-sigs rv))
         (for [rv [:o :l :d]
               arg1 [:o :l :d]]
           (dual-arg-sigs rv arg1))
         (for [rv [:o :l :d]
               arg1 [:o :l :d]
               arg2 [:o :l :d]]
           (triple-arg-sigs rv arg1 arg2))
         (for [rv [:o :l :d]
               arg1 [:o :l :d]
               arg2 [:o :l :d]
               arg3 [:o :l :d]]
           (quad-arg-sigs rv arg1 arg2 arg3)))
        lznc/apply-concat
        (lznc/remove #(every? (fn [a](= :o a)) %)))))


(defn writeit
  []
  (with-open [w (io/writer (io/output-stream "src/ham_fisted/primitive_invoke.clj"))]
    (.write w (str "(ns ham-fisted.primitive-invoke
\"For statically traced calls the Clojure compiler calls the primitive version of type-hinted functions
  and this makes quite a difference in tight loops.  Often times, however, functions are passed by values
  or returned from if-statements and then you need to explicitly call the primitive overload - this makes
  that pathway less verbose.\")\n\n"))
    (doseq [sig ifn-sigs]
      (let [sname (apply str (map name sig))
            ifn-name (str "clojure.lang.IFn$" (.toUpperCase sname))]
        (.write w (str "(defn ->" sname " ^" ifn-name " [f]
  (if (instance? " ifn-name " f)
    f
    (throw (RuntimeException. (str f \" is not an instance of" ifn-name "\")))))\n"))
        (.write w (str "(defmacro " sname " [f"))
        (dotimes [i (dec (count sig))]
          (.write w (str " "))
          (.write w (str "arg" i)))
        (.write w "]\n")
        (.write w (str "`(.invokePrim ~f"))
        (dotimes [i (dec (count sig))]
          (.write w (str " "))
          (.write w (str "~arg" i)))
        (.write w "))\n")))))


(comment
  (writeit)
  )


================================================
FILE: deps.edn
================================================
{:paths ["src" "resources" "target/classes"]
 :deps {it.unimi.dsi/fastutil-core {:mvn/version "8.5.14"}
        com.github.ben-manes.caffeine/caffeine {:mvn/version "2.9.3"}
        net.openhft/zero-allocation-hashing {:mvn/version "0.27ea0"}}

 :aliases
 {;; Run with clj -T:build function-in-build
  :dev
  {:extra-deps {;;org.clojure/clojure {:mvn/version "1.12.0-CN-SNAPSHOT"}
                org.clojure/clojure {:mvn/version "1.12.0"}
                criterium/criterium {:mvn/version "0.4.6"}
                techascent/tech.ml.dataset {:mvn/version "7.032"}
                ch.qos.logback/logback-classic {:mvn/version "1.1.3"}
                kixi/stats {:mvn/version "0.5.5"}
                org.clojure/data.int-map {:mvn/version "1.3.0"}
                techascent/tech.viz {:mvn/version "6.00-beta-16-4"}
                com.clojure-goes-fast/clj-java-decompiler {:mvn/version "0.3.6"}
                com.clojure-goes-fast/clj-memory-meter {:mvn/version "0.3.0"}
                com.clojure-goes-fast/clj-async-profiler {:mvn/version "1.6.2"}}
   :extra-paths ["dev/src" "test"]
   :jvm-opts ["-Djdk.attach.allowAttachSelf=true"
              "-XX:+EnableDynamicAgentLoading"
              "--illegal-access=permit"]}
  :nospec {:jvm-opts ["-Dclojure.spec.skip-macros=true" "-Xverify:none"]}
  :jdk-19 {:jvm-opts ["-Djdk.attach.allowAttachSelf=true" "--illegal-access=permit"]}
  :build
  {:deps {io.github.clojure/tools.build {:mvn/version "0.10.5"}}
   :ns-default build}
  :clj-kondo {:extra-deps {clj-kondo/clj-kondo {:mvn/version "2024.08.29"}}
              :main-opts ["-m" "clj-kondo.main"]}
  :kaocha-test
  {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}
                lambdaisland/kaocha-junit-xml {:mvn/version "1.17.101"}
                lambdaisland/kaocha-cloverage {:mvn/version "1.1.89"}}
   :extra-paths ["test"]
   :main-opts ["-m" "kaocha.runner"]}
  :test
  {:extra-deps {com.cognitect/test-runner
                {:git/url "https://github.com/cognitect-labs/test-runner"
                 :sha "209b64504cb3bd3b99ecfec7937b358a879f55c1"}
                ch.qos.logback/logback-classic {:mvn/version "1.1.3"}}
   :extra-paths ["test"]
   :main-opts ["-m" "cognitect.test-runner"]}
  :codox
  {:extra-deps {codox-theme-rdash/codox-theme-rdash {:mvn/version "0.1.2"}
                nrepl/nrepl {:mvn/version "1.3.0"}
                cider/cider-nrepl {:mvn/version "0.50.2"}
                com.cnuernber/codox {:mvn/version "1.001"}}
   :exec-fn codox.main/-main
   :exec-args {:group-id "com.cnuernber"
               :artifact-id "ham-fisted"
               :version "3.029"
               :name "Ham-Fisted"
               :description "High Performance Clojure Primitives"
               :metadata {:doc/format :markdown}
               :html {:transforms [[:head] [:append [:script {:async true
                                                              :src "https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM"}]]
                                   [:head] [:append [:script "window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-XJYNJF48RM');"]]]}
               :themes [:rdash]
               :source-paths ["src"]
               :output-path "docs"
               :doc-paths ["topics"]
               :source-uri "https://github.com/cnuernber/ham-fisted/blob/master/{filepath}#L{line}"
               :namespaces [ham-fisted.api
                            ham-fisted.lazy-noncaching
                            ham-fisted.protocols
                            ham-fisted.set
                            ham-fisted.function
                            ham-fisted.mut-map
                            ham-fisted.reduce
                            ham-fisted.hlet
                            ham-fisted.primitive-invoke
                            ham-fisted.bloom-filter
                            ham-fisted.defprotocol
                            ham-fisted.iterator
                            ham-fisted.process
                            ham-fisted.profile
                            ham-fisted.fjp
                            ham-fisted.spliterator]}}
  :deploy
  {:replace-deps {slipset/deps-deploy {:mvn/version "0.2.2"}}
   :exec-fn deps-deploy.deps-deploy/deploy
   :exec-args {:installer :remote
               :sign-releases? true
               :artifact "target/ham-fisted.jar"}}
  :install
  {:replace-deps {slipset/deps-deploy {:mvn/version "0.2.2"}}
   :exec-fn deps-deploy.deps-deploy/deploy
   :exec-args {:installer :local
               :artifact "target/ham-fisted.jar"}}}}


================================================
FILE: dev/resources/logback.xml
================================================
<configuration debug="false">
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="info">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>


================================================
FILE: dev/src/ham_fisted/analysis.clj
================================================
(ns ham-fisted.analysis
  (:require [clojure.edn :as edn]
            [charred.api :as charred]
            [applied-science.darkstar :as darkstar]
            [clojure.java.io :as io]))



(defn plot-perf-test
  [testgroup options]
  (let [group-item (first testgroup)
        testname (:test group-item)
        numeric? (:numeric? group-item)
        bytes? (= (:test group-item)
                  :hashmap-bytes)
        baseline (or (:baseline options) :clj)
        testdata (->> testgroup
                      (mapcat (if bytes?
                                (fn [group-item]
                                  (let [n-elems (:n-elems group-item)
                                        clj-bytes (:clj group-item)]
                                    (->> (dissoc group-item :test :numeric? :n-elems)
                                         (map (fn [kv]
                                                {:datastructure (key kv)
                                                 :n-elems n-elems
                                                 :norm-bytes (double (/ (val kv) clj-bytes))})))))
                                (fn [group-item]
                                  (let [n-elems (:n-elems group-item)
                                        clj-val (get-in group-item [baseline :mean-μs])]
                                    (->> group-item
                                         (map (fn [kv]
                                                (let [k (key kv)
                                                      val (val kv)]
                                                  (when-let [us (get val :mean-μs)]
                                                    {:datastructure k
                                                     :norm-mean-μs (double (/ us clj-val))
                                                     :n-elems n-elems}))))
                                         (remove nil?))))))
                      (sort-by :datastructure)
                      (vec))
        chart-title (str (name testname) "-" (if numeric?
                                               "numeric"
                                               "non-numeric"))
        chartname (str "charts/" chart-title ".svg")]
    (io/make-parents chartname)
    (if bytes?
      (spit chartname
            (-> {:$schema "https://vega.github.io/schema/vega-lite/v5.1.0.json"
                 :mark {:type :line
                        :point true}
                 :title chart-title
                 :width 800
                 :height 600
                 :data {:values testdata}
                 :encoding
                 {:y {:field :norm-bytes, :type :quantitative :axis {:grid false}}
                  :x {:field :n-elems :type :quantitative :scale {:type :log}}
                  :color {:field :datastructure :type :nominal}
                  :shape {:field :datastructure :type :nominal}}}
                (charred/write-json-str)
                (darkstar/vega-lite-spec->svg)))
      (spit chartname
            (-> {:$schema "https://vega.github.io/schema/vega-lite/v5.1.0.json"
                 :mark {:type :line
                        :point true}
                 :title chart-title
                 :width 800
                 :height 600
                 :data {:values testdata}
                 :encoding
                 {:y {:field :norm-mean-μs, :type :quantitative :axis {:grid false}}
                  :x {:field :n-elems :type :quantitative :scale {:type :log}}
                  :color {:field :datastructure :type :nominal}
                  :shape {:field :datastructure :type :nominal}}}
                (charred/write-json-str)
                (darkstar/vega-lite-spec->svg))))
    ;;testdata
    ))

(defn- process-files
  ([fnames] (process-files fnames nil))
  ([fnames options]
   (->> fnames
        (mapcat #(edn/read-string (slurp %)))
        (group-by (juxt :numeric? :test))
        (vals)
        (map #(plot-perf-test % options))
        (dorun))
   :ok))

(defn general-hashmap-analysis
  []
  (process-files ["results/general-hashmap.edn"])
  )


(defn random-update-analysis
  []
  (process-files ["results/random-update.edn"]))


(defn union-analysis
  []
  (process-files ["results/union-overlapping.edn"
                  "results/union-disj.edn"
                  "results/union-reduce.edn"
                  "results/update-values.edn"]))

(defn typed-reduction-analysis
  []
  (process-files ["results/typed-reductions.edn"]))


(defn typed-parallel-reduction-analysis
  []
  (process-files ["results/typed-parallel-reductions.edn"]))

(defn union-reduce-transient
  []
  (process-files ["results/union-reduce-transient.edn"] {:baseline :hamf-hashmap})
  )


(defn persistent-vector
  []
  (process-files ["results/persistent-vector.edn"]))


(defn sort-by-analysis
  []
  (process-files ["results/sort-by.edn"]))


================================================
FILE: dev/src/ham_fisted/benchmark.clj
================================================
(ns ham-fisted.benchmark
  (:require [criterium.core :as c]))


(defmacro benchmark-us
  "Benchmark an op, returning a map of :mean and :variance in μs."
  [op]
  `(let [bdata# (c/quick-benchmark ~op nil)]
     {:mean-μs (* (double (first (:mean bdata#))) 1e6)
      :variance-μs (* (double (first (:variance bdata#))) 1e6)}))


================================================
FILE: dev/src/ham_fisted/protocol_perf.clj
================================================
(ns ham-fisted.protocol-perf
  (:require [ham-fisted.defprotocol :as hamf-defproto]
            [ham-fisted.protocols :as hamf-proto]
            [ham-fisted.lazy-noncaching :as lznc]
            [ham-fisted.api :as hamf]
            [ham-fisted.reduce :as hamf-rf]
            [clojure.pprint :as pp])
  (:import [java.util LongSummaryStatistics]
           [java.util.function LongConsumer])
  (:gen-class))

(set! *unchecked-math* :warn-on-boxed)
(set! *warn-on-reflection* true)

(hamf-defproto/defprotocol HamfMemsize
  (^long hamf-memsize [m]))

(hamf-defproto/extend Double HamfMemsize {:hamf-memsize 24})
(hamf-defproto/extend Long HamfMemsize {:hamf-memsize 24})
(hamf-defproto/extend clojure.lang.Keyword HamfMemsize {:hamf-memsize 48})

(hamf-defproto/extend-protocol HamfMemsize
  String
  (hamf-memsize [s] (+ 24 (.length ^String s)))
  java.util.Collection
  (hamf-memsize [c] (hamf/lsum (lznc/map (fn ^long [d] (+ 24 (hamf-memsize d))) c)))
  java.util.Map
  (hamf-memsize [c] (hamf/lsum (lznc/map (fn ^long [kv]
                                           (+ 36 (+ (hamf-memsize (key kv)) (hamf-memsize (val kv)))))
                                         c))))

(clojure.core/defprotocol CoreMemsize
  (core-memsize [m]))

(clojure.core/extend-protocol CoreMemsize
  Double (core-memsize [d] 24)
  Long (core-memsize [l] 24)
  clojure.lang.Keyword (core-memsize [k] 48)
  String (core-memsize [s] (+ 24 (.length ^String s)))
  java.util.Collection
  (core-memsize [c]
    (hamf/lsum (lznc/map (fn ^long [d] (+ 24 (long (core-memsize d)))) c))
    #_(reduce
       (fn [s v] (+ s 24 (core-memsize v)))
       0
       c))
  java.util.Map
  (core-memsize [m]
    (hamf/lsum (lznc/map (fn ^long [kv]
                           (+ 36 (+ (long (core-memsize (key kv)))
                                    (long (core-memsize (val kv))))))
                         m))
    #_(reduce
       (fn [s [k v]] (+ s 36 (core-memsize k) (core-memsize v)))
       0
       m)))

(def test-datastructure
  {:a "hello"
   :b 24
   :c (into [] (repeat 1000 (rand)))
   :d (into [] (repeat 1000 1))})


(def measure-data (into [] (repeat 10000 test-datastructure)))

(defn multithread-test
  [measure-fn]
  (hamf/lsum (hamf/pmap measure-fn measure-data)))

(hamf-defproto/defprotocol PPrimitiveArgs
  (^double pargs [m ^long b]))

(hamf-defproto/extend-type String
  PPrimitiveArgs
  (pargs [m b]
    (+ 1.0 (+ (.length m) b))))

(hamf-defproto/extend-type Double
  PPrimitiveArgs
  (pargs [m b]
    (+ 1.0 (+ (double m) b))))

(defprotocol CorePPrimitiveArgs
  (core-pargs [m b]))

(extend-type String
  CorePPrimitiveArgs
  (core-pargs [m b]
    (+ 1.0 (+ (.length m) (long b)))))

(extend-type Double
  CorePPrimitiveArgs
  (core-pargs [m b]
    (+ 1.0 (+ (double b) (long b)))))

(def strs (mapv str (range 100000)))
(def strs-and-doubles (vec (take 100000 (interleave strs (map double (range 100000))))))

(defn reduce-count
  [data]
  (reduce (fn [^long acc v] (inc acc)) 0 data))

(defprotocol TestProto
  (f [this a b]))

(extend-protocol TestProto
  String
  (f [this a b] 1)
  Long
  (f [this a b] 1)
  Double
  (f [this a b] 1)
  java.util.Collection
  (f [this a b]
    (reduce-count (lznc/map #(f % [] :x) this))))

(hamf-defproto/defprotocol HFTestProto
  (hf [this a b]))

(hamf-defproto/extend-protocol HFTestProto
  String
  (hf [this a b] 1)
  Long
  (hf [this a b] 1)
  Double
  (hf [this a b] 1)
  java.util.Collection
  (hf [this a b]
    (reduce-count (lznc/map #(hf % [] :x) this))))

(defn explore!
  [n]
  (println "========= Exploring general protocol pathways ========")
  (let [l (vec (take 10000 (cycle ["foo" 5678 3.14 (vec (take 10000 (cycle ["foo" 5678 3.14])))])))]
    (dotimes [i n]
      (println "attempt" i)
      (println "map f")
      (time (reduce-count (lznc/map #(f % [] :x) l)))
      (println "map fast-f")
      (time (reduce-count (lznc/map #(hf % [] :x) l)))
      (println "pmap f")
      (time (reduce-count (hamf/pmap #(f % [] :x) l)))
      (println "pmap fast-f")
      (time (reduce-count (lznc/map identity (hamf/pmap #(hf % [] :x) l))))))
  :done)

(defn -main
  [& args]
  (println "Core protocols")
  (dotimes [idx 5]
    (time (multithread-test core-memsize)))

  (println "hamf protocols")
  (dotimes [idx 5]
    (time (multithread-test hamf-memsize)))

  (println "serial single type core pargs")
  (dotimes [idx 5]
    (time 
     (dotimes [idx 10]
       (hamf/sum-fast (lznc/map (fn ^double [s] (core-pargs s 100)) strs)))))

  (println "serial single type hamf pargs")
  (dotimes [idx 5]
    (time
     (dotimes [idx 10]
       (hamf/sum-fast (lznc/map (fn ^double [s] (pargs s 100)) strs)))))

  (println "parallel single type core pargs")
  (dotimes [idx 5]
    (time 
     (dotimes [idx 10]
       (hamf/sum (lznc/map (fn ^double [s] (core-pargs s 100)) strs)))))

  (println "parallel single type hamf pargs")
  (dotimes [idx 5]
    (time 
     (dotimes [idx 10]
       (hamf/sum (lznc/map (fn ^double [s] (pargs s 100)) strs)))))


  (println "serial dual type core pargs")
  (dotimes [idx 5]
    (time 
     (dotimes [idx 10]
       (hamf/sum-fast (lznc/map (fn ^double [s] (core-pargs s 100)) strs-and-doubles)))))

  (println "serial dual type hamf pargs")
  (dotimes [idx 5]
    (time
     (dotimes [idx 10]
       (hamf/sum-fast (lznc/map (fn ^double [s] (pargs s 100)) strs-and-doubles)))))

  (println "parallel dual type core pargs")
  (dotimes [idx 5]
    (time 
     (dotimes [idx 10]
       (hamf/sum (lznc/map (fn ^double [s] (core-pargs s 100)) strs-and-doubles)))))

  (println "parallel dual type hamf pargs")
  (dotimes [idx 5]
    (time 
     (dotimes [idx 10]
       (hamf/sum (lznc/map (fn ^double [s] (pargs s 100)) strs-and-doubles)))))

  (explore! 4)
 
  :ok)


================================================
FILE: dev/src/perftest.clj
================================================
(ns perftest
  (:require [ham-fisted.api :as hamf]
            [ham-fisted.function :as hamf-fn]
            [ham-fisted.reduce :as hamf-rf]
            [ham-fisted.lazy-noncaching :as lznc]
            [ham-fisted.benchmark :refer [benchmark-us] :as bench]
            [clojure.data.int-map :as i]
            [tech.v3.datatype :as dtype]
            [tech.v3.datatype.functional :as dfn]
            [clojure.tools.logging :as log]
            [clojure.pprint :as pp]
            [clojure.java.shell :as sh]
            [clojure.java.io :as io]
            [clojure.string :as str]
            [criterium.core :as crit]
            [clj-memory-meter.core :as mm])
  (:import [java.util HashMap ArrayList Map List Map$Entry ArrayList]
           [java.util.function BiFunction]
           [ham_fisted IMutList Sum$SimpleSum Sum Consumers$IncConsumer]
           [clojure.lang PersistentHashMap])
  (:gen-class))


(set! *unchecked-math* :warn-on-boxed)



(defn long-map-data
  [^long n-elems]
  (lznc/->random-access
   (lznc/object-array
    (lznc/map
     #(hamf/vector % %)
     (lznc/repeatedly n-elems #(long (rand-int 100000)))))))


(defn kwd-map-data
  [^long n-elems]
  (lznc/->random-access
   (lznc/object-array
    (lznc/map
     #(hamf/vector (keyword (str %)) %)
     (lznc/repeatedly n-elems #(rand-int 100000))))))


(def map-non-numeric-constructors
  {:clj #(into {} %)
   #_#_:hamf-trie hamf/mut-trie-map
   :hamf-hashmap hamf/mut-map
   :java hamf/java-hashmap})


(def map-numeric-constructors
  {:hamf-long-map hamf/mut-long-hashtable-map
   :clj-int-map #(into (i/int-map) %)})

(defn map-constructors
  [numeric?]
  (merge map-non-numeric-constructors
         (when numeric?
           map-numeric-constructors)))


(defn initial-maps
  [mapsc data]
  (hamf/mapmap #(vector (key %) ((val %) data)) mapsc))


(defn hashmap-perftest
  [data]
  (let [numeric? (number? (ffirst data))
        n-elems (count data)
        _ (log/info (str "Running map benchmark on " (if numeric?
                                                       "numeric "
                                                       "non-numeric ")
                         "data with n=" n-elems))
        map-constructors (map-constructors numeric?)
        map-data (initial-maps map-constructors data)]
    [(merge (hamf/mapmap (fn [entry]
                           [(key entry) (benchmark-us ((val entry) data))])
                         map-constructors)
            {:n-elems n-elems :test :hashmap-construction :numeric? numeric?})
     (merge (hamf/mapmap #(vector (key %)
                                  (benchmark-us
                                   (reduce (fn [acc data]
                                             (.get ^Map acc (data 0)) acc)
                                           (val %)
                                           data)))
                         map-data)
            {:n-elems n-elems :test :hashmap-access :numeric? numeric?})
     (merge (hamf/mapmap #(vector (key %)
                                  (benchmark-us
                                   (fn [acc map]
                                     (reduce (fn [& kv] kv)
                                             nil
                                             (val %)))))
                         map-data)
            {:n-elems n-elems :test :hashmap-reduction :numeric? numeric?})
     (merge (hamf/mapmap #(vector (key %) (mm/measure (val %) :bytes true))
                         map-data)
            {:n-elems n-elems :test :hashmap-bytes  :numeric? numeric?})]))


(defn- spit-data
  [testname data]
  (let [data (vec data)
        fname (str "results/" testname ".edn")]
    (io/make-parents fname)
    (spit fname (pr-str data))))


(defn general-hashmap
  []
  (->> (for [n-elems [4 10 100 1000 10000 1000000
                      ]
             numeric? [true false
                       ]]
         (hashmap-perftest (if numeric?
                             (long-map-data n-elems)
                             (kwd-map-data n-elems))))
       (lznc/apply-concat)
       (vec)
       (spit-data "general-hashmap")))


(defn random-updates
  []
  (->> (for [n-elems [ 4 10
                      100
                       1000 10000 1000000
                      ]
             numeric? [true false
                       ]
             ]
         (do
           (log/info (str "random-update benchmark on " (if numeric?
                                                          "numeric "
                                                          "non-numeric ")
                          "data with n=" n-elems))
           (let [cycle-size 1000
                 n-elems (long n-elems)
                 data (vec (take (max cycle-size n-elems) (cycle (repeatedly (min n-elems cycle-size) #(long (rand-int 1000))))))
                 data (if numeric? data (map (comp keyword str) data))
                 init-maps (initial-maps (map-constructors numeric?) nil)]
             (merge (hamf/mapmap (fn [kv]
                                   (let [m (val kv)
                                         immut-path? (instance? clojure.lang.IPersistentMap m)]
                                     [(key kv)
                                      (if immut-path?
                                        (benchmark-us (reduce (fn [acc v]
                                                                (assoc! acc v (unchecked-inc (long (get acc v 0)))))
                                                              (transient m)
                                                              data))
                                        (let [cfn (hamf-fn/function _v (Consumers$IncConsumer.))]
                                          (benchmark-us (reduce (fn [^Map acc v]
                                                                  (.inc ^Consumers$IncConsumer
                                                                        (.computeIfAbsent acc v cfn))
                                                                  acc)
                                                                m
                                                                data))))]))
                                 init-maps)
                    {:n-elems n-elems :numeric? numeric? :test :random-update}))))
       (vec)
       (spit-data "random-update")))


#_(defn union-overlapping
  []
  (->> (for [n-elems [4 10
                      100
                      1000 10000 1000000
                      ]
             numeric? [true false
                       ]
             ]
         (do
           (log/info (str "union-overlapping benchmark on " (if numeric?
                                                              "numeric "
                                                              "non-numeric ")
                          "data with n=" n-elems))
           (let [data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))
                 constructors (map-constructors numeric?)
                 init-maps (initial-maps constructors data)
                 merge-bfn (hamf-fn/bi-function a b (+ (long a) (long b)))]
             (merge (hamf/mapmap (fn [kv]
                                   (let [m (hamf/persistent! (val kv))]
                                     [(key kv)
                                      (cond
                                        (instance? clojure.lang.IPersistentMap m)
                                        (benchmark-us (merge-with merge-bfn m m))
                                        (instance? BitmapTrieCommon$MapSet m)
                                        (benchmark-us (.union ^BitmapTrieCommon$MapSet m m merge-bfn))
                                        :else
                                        (let [map-c (get constructors (key kv))]
                                          (benchmark-us (hamf/map-union merge-bfn (map-c m) m))))]))
                                 init-maps)
                    {:n-elems n-elems :numeric? numeric? :test :union-overlapping}))))
       (vec)
       (spit-data "union-overlapping")
       ))


#_(defn union-disj
  []
  (->> (for [n-elems [4 10
                      100
                      1000 10000 1000000
                      ]
             numeric? [true false
                       ]
             ]
         (do
           (log/info (str "union-disj benchmark on " (if numeric?
                                                              "numeric "
                                                              "non-numeric ")
                          "data with n=" n-elems))
           (let [n-elems (long n-elems)
                 data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))
                 lhs-data (vec (take (quot n-elems 2) data))
                 rhs-data (vec (drop (- n-elems (count lhs-data)) data))
                 constructors (map-constructors numeric?)
                 lhs-maps (initial-maps constructors lhs-data)
                 rhs-maps (initial-maps constructors rhs-data)
                 merge-bfn (hamf-fn/bi-function a b (+ (long a) (long b)))]
             (merge (hamf/mapmap (fn [kv]
                                   ;;Make sure we can't edit lhs
                                   (let [lhs (hamf/persistent! (val kv))
                                         rhs (rhs-maps (key kv))]
                                     [(key kv)
                                      (cond
                                        (instance? clojure.lang.IPersistentMap lhs)
                                        (benchmark-us (merge-with merge-bfn lhs rhs))
                                        (instance? BitmapTrieCommon$MapSet lhs)
                                        (benchmark-us (.union ^BitmapTrieCommon$MapSet (hamf/transient lhs) rhs merge-bfn))
                                        :else
                                        (let [map-c (get constructors (key kv))]
                                          (benchmark-us (hamf/map-union merge-bfn (map-c lhs ) rhs))))]))
                                 lhs-maps)
                    {:n-elems n-elems :numeric? numeric? :test :union-disj}))))
       (vec)
       (spit-data "union-disj")
       ))


#_(defn union-reduce
  []
  (->> (for [n-elems [ 4 10
                      100
                       1000 10000 1000000
                      ]
             numeric? [true false
                       ]
             ]
         (do
           (log/info (str "union-reduce benchmark on " (if numeric?
                                                              "numeric "
                                                              "non-numeric ")
                          "data with n=" n-elems))
           (let [data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))
                 constructors (map-constructors numeric?)
                 init-maps (initial-maps constructors data)
                 merge-bfn (hamf-fn/bi-function a b (+ (long a) (long b)))]
             (merge (hamf/mapmap (fn [kv]
                                   (let [m (hamf/persistent! (val kv))
                                         mseq (vec (repeat 16 m))]
                                     [(key kv)
                                      (cond
                                        (instance? clojure.lang.IPersistentMap m)
                                        (benchmark-us (reduce #(merge-with merge-bfn %1 %2)
                                                              m
                                                              mseq))
                                        (instance? BitmapTrieCommon$MapSet m)
                                        (benchmark-us (reduce #(.union ^BitmapTrieCommon$MapSet %1 %2 merge-bfn)
                                                              m
                                                              mseq))
                                        :else
                                        (let [map-c (get constructors (key kv))]
                                          (benchmark-us (reduce #(hamf/map-union merge-bfn %1 %2)
                                                                (map-c m)
                                                                mseq))))]))
                                 init-maps)
                    {:n-elems n-elems :numeric? numeric? :test :union-reduce}))))
       (vec)
       (spit-data "union-reduce")))


(defn union-reduce-transient
  "Comparing reducing into a single transient container vs. doing a shallow clone every union call."
  []
  (->> (for [n-elems [ 4 10
                      100
                       1000 10000 1000000
                      ]
             numeric? [true
                       ]
             ]
         (do
           (log/info (str "union-reduce-transient benchmark on " (if numeric?
                                                                   "numeric "
                                                                   "non-numeric ")
                          "data with n=" n-elems))
           (let [data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))
                 constructors (map-constructors numeric?)
                 hashmap (hamf/mut-map data)
                 long-hashmap (hamf/mut-map data)
                 init-maps {:hamf-hashmap (persistent! hashmap)
                            :hamf-long-map (persistent! long-hashmap)
                            :hamf-trans-hashmap (with-meta (persistent! hashmap) {:transient? true})
                            :hamf-trans-long-map (with-meta (persistent! long-hashmap) {:transient? true})}
                 merge-bfn (hamf-fn/bi-function a b (+ (long a) (long b)))]
             (merge (hamf/mapmap (fn [kv]
                                   (let [m (val kv)
                                         mseq (vec (repeat 16 m))]
                                     [(key kv)
                                      (benchmark-us (reduce #(.union (hamf/as-map-set %1) %2 merge-bfn)
                                                            (if (:transient? (meta m))
                                                              (transient m)
                                                              m)
                                                            mseq))]))
                                 init-maps)
                    {:n-elems n-elems :numeric? numeric? :test :union-reduce-transient}))))
       (vec)
       (spit-data "union-reduce-transient")))


#_(defn update-values
  []
  (->> (for [n-elems [ 4 10
                      100
                       1000 10000 1000000
                      ]
             numeric? [true false
                       ]
             ]
         (do
           (log/info (str "update-values benchmark on " (if numeric?
                                                          "numeric "
                                                          "non-numeric ")
                          "data with n=" n-elems))
           (let [data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))
                 constructors (map-constructors numeric?)
                 init-maps (initial-maps constructors data)
                 update-bfn (hamf-fn/bi-function k v (unchecked-inc (long v)))]
             (merge (hamf/mapmap (fn [kv]
                                   (let [m (val kv)]
                                     [(key kv)
                                      (cond
                                        ;;for whatever reason update-vals isn't found during uberjar build
                                        (instance? clojure.lang.IPersistentMap m)
                                        (benchmark-us (update-vals m unchecked-inc))
                                        (instance? ImmutValues m)
                                        (benchmark-us (.immutUpdateValues ^ImmutValues m update-bfn))
                                        :else
                                        (benchmark-us (.replaceAll ^Map ((constructors (key kv)) m) update-bfn)))]))
                                 init-maps)
                    {:n-elems n-elems :numeric? numeric? :test :update-values}))))
       (vec)
       (spit-data "update-values")))


(deftype LongAccum [^{:unsynchronized-mutable true
                      :tag long} val]
  clojure.lang.IDeref
  (deref [this] val)
  java.util.function.LongConsumer
  (accept [this v] (set! val (+ v val))))


(defn typed-reductions
  []
  (->>
   (for [n-elems [ 4 10
                  100
                  1000 10000 1000000                  ]]
     (do
       (log/info (str "typed reduction benchmark on " (if true
                                                        "numeric "
                                                        "non-numeric ")
                      "data with n=" n-elems))
       (merge
        {:clj (benchmark-us (transduce (comp (map #(+ (long %) 10)) (filter #(== 0 (rem (long %) 2))))
                                       + 0 (hamf/range n-elems)))
         :clj-typed (benchmark-us (transduce (comp (map (hamf-fn/long-unary-operator a (+ a 10)))
                                                   (filter (hamf-fn/long-predicate a (== 0 (rem a 2)))))
                                             (reify ham_fisted.IFnDef$LLL
                                               (invokePrim [this a b] (+ a b))
                                               (invoke [this a] a)) 0
                                             (hamf/range n-elems)))
         :hamf-partial (benchmark-us (->> (hamf/range n-elems)
                                          (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))
                                          (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))
                                          (reduce (hamf-fn/long-binary-operator a b (+ a b)) 0)))
         :hamf-deftype-consumer (benchmark-us (->> (hamf/range n-elems)
                                                   (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))
                                                   (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))
                                                   (reduce hamf-rf/long-consumer-accumulator (LongAccum. 0))))
         :hamf-java-consumer (benchmark-us (->> (hamf/range n-elems)
                                                (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))
                                                (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))
                                                (reduce hamf-rf/long-consumer-accumulator (ham_fisted.LongAccum. 0))))}
        {:n-elems n-elems :numeric? true :test :typed-reductions})))
   (vec)
   (spit-data "typed-reductions-intel")))


(defn typed-parallel-reductions
  []
  (->>
   (for [n-elems [1000 1000000
                  100000000
                  ]]
     (do
       (log/info (str "parallel reduction benchmark on " (if true
                                                        "numeric "
                                                        "non-numeric ")
                      "data with n=" n-elems))
       (let [ops (hamf-rf/options->parallel-options {:min-n 10})]
         (merge
          {:clj (benchmark-us (transduce (comp (map #(+ (long %) 10)) (filter #(== 0 (rem (long %) 2))))
                                         + 0 (hamf/range n-elems)))
           :hamf-untyped (benchmark-us (->> (hamf/range n-elems)
                                            (lznc/map #(+ (long %) 10))
                                            (lznc/filter #(== 0 (rem (long %) 2)))
                                            (hamf-rf/preduce (constantly 0)
                                                          #(+ (long %1) (long %2))
                                                          #(+ (long %1) (long %2))
                                                          ops)))
           :hamf-typed (benchmark-us (->> (hamf/range n-elems)
                                          (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))
                                          (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))
                                          (hamf-rf/preduce (constantly 0)
                                                        (hamf-fn/long-binary-operator a b (+ a b))
                                                        (hamf-fn/long-binary-operator a b (+ a b))
                                                        ops)))
           :hamf-consumer (benchmark-us (->> (hamf/range n-elems)
                                             (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))
                                             (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))
                                             (hamf-rf/preduce #(ham_fisted.LongAccum. 0)
                                                           hamf-rf/long-consumer-accumulator
                                                           hamf-rf/reducible-merge
                                                           ops)))}
          {:n-elems n-elems :numeric? true :test :typed-parallel-reductions}))))
   (vec)
   (spit-data "typed-parallel-reductions")
   ))


(def persistent-vector-constructors
  {:clj vec
   :hamf hamf/immut-list
   :hamf-objary #(hamf/immut-list (hamf/object-array %))
   :java #(doto (ArrayList.)
            (.addAll (hamf/->random-access %)))})


(defn persistent-vector-perftest
  []
  (->> (for [n-elems [4 10
                      100
                      1000 10000 100000]]
         (do
           (log/info (str "persistent vector perftest with n= " n-elems))
           [(merge (hamf/mapmap (fn [kv]
                                  [(key kv)
                                   (benchmark-us ((val kv) (range n-elems)))])
                                persistent-vector-constructors)
                   {:n-elems n-elems :numeric? true :test :vector-construction})
            (merge (hamf/mapmap (fn [kv]
                                  (let [data ((val kv) (range n-elems))]
                                    [(key kv)
                                     (benchmark-us (dotimes [idx n-elems]
                                                     (.get ^List data idx)))]))
                                persistent-vector-constructors)
                   {:n-elems n-elems :numeric? true :test :vector-access})
            (merge (hamf/mapmap (fn [kv]
                                  (let [data ((val kv) (range n-elems))]
                                    [(key kv)
                                     (benchmark-us (.toArray ^List data))]))
                                persistent-vector-constructors)
                   {:n-elems n-elems :numeric? true :test :to-object-array})
            (merge (hamf/mapmap (fn [kv]
                                  (let [data (double-array (range n-elems))]
                                    [(key kv)
                                     (benchmark-us ((val kv) data))]))
                                persistent-vector-constructors)
                   {:n-elems n-elems :numeric? true :test :from-double-array})
            ]))
       (lznc/apply-concat)
       (vec)
       (spit-data "persistent-vector")))


(defn sort-by-perftest
  []
  (->>
   (for [n-elems [4 10
                  100
                  1000 10000 100000
                  1000000
                  ]]
     (do
       (log/info (str "sort-by perftest with n= " n-elems))
       (let [data (mapv (fn [idx]
                          {:a 1
                           :b idx})
                        (shuffle (range n-elems)))]
         {:clj (benchmark-us (sort-by :b data))
          :hamf (benchmark-us (hamf/sort-by :b data))
          :hamf-typed (benchmark-us (hamf/sort-by (hamf-fn/obj->long d (long (d :b))) data))
          :n-elems n-elems
          :test :sort-by
          :numeric? true})))
   (vec)
   (spit-data "sort-by")))


(defn concatv-perftest
  []
  (->>
   (for [n-elems [4 10
                  100
                  1000 10000 100000
                  1000000
                  ]]
     (do
       (log/info (str "concatv perftest with n= " n-elems))
       (let [data (vec (repeat 10 (range n-elems)))]
         {:clj (benchmark-us (into [] cat data))
          :hamf (benchmark-us (hamf/apply-concatv data))
          :hamf-objarry (benchmark-us (apply hamf/concata data))
          :n-elems n-elems
          :test :concatv
          :numeric? true})))
   (vec)
   (spit-data "concatv")))


(defn vec-equals-perftest
  []
  (->>
   (for [n-elems [4 10
                  100
                  1000 10000 100000
                  ]
         numeric [true false]]
     (do
       (log/info (str "concatv perftest with n= " n-elems))
       (let [src-data (if numeric
                        (range n-elems)
                        (map (comp str keyword) (range n-elems)))]
         {:clj (let [lhs (vec src-data)
                     rhs (vec src-data)]
                 (benchmark-us (= lhs rhs)))
          :hamf (let [lhs (hamf/vec src-data)
                      rhs (hamf/vec src-data)]
                  (benchmark-us (= lhs rhs)))
          :n-elems n-elems
          :test :equals
          :numeric? numeric})))
   (vec)
   (spit-data "vec-equals")))



(defn -main
  [& args]
  ;;shutdown test
  (persistent-vector-perftest)
  #_(concatv-perftest)
  #_(vec-equals-perftest)
  #_(let [perf-data (process-dataset (profile))
        vs (System/getProperty "java.version")
        mn (machine-name)
        gs (git-sha)
        fname (str "results/" gs "-" mn "-jdk-" vs ".edn")]
    (print-dataset perf-data)
    (println "Results stored to:" fname)
    ;;(spit fname (with-out-str (pp/pprint {:machine-name mn :git-sha gs :jdk-version vs :dataset perf-data})))
    )
  (println "exiting"))


================================================
FILE: docs/Reductions.html
================================================
<!DOCTYPE html PUBLIC ""
    "">
<html><head><meta charset="UTF-8" /><title>Reductions</title><script async="true" src="https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM"></script><script>window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-XJYNJF48RM');</script><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="highlight/solarized-light.css" /><script type="text/javascript" src="highlight/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a> with <a href="https://github.com/xsc/codox-theme-rdash">RDash UI</a> theme</h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Ham-Fisted</span> <span class="project-version">3.029</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1  current"><a href="Reductions.html"><div class="inner"><span>Reductions</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ham-fisted</span></div></div></li><li class="depth-2 branch"><a href="ham-fisted.api.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>api</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.bloom-filter.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bloom-filter</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.defprotocol.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>defprotocol</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.fjp.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>fjp</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.function.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>function</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.hlet.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>hlet</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.iterator.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>iterator</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.lazy-noncaching.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>lazy-noncaching</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.mut-map.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mut-map</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.primitive-invoke.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>primitive-invoke</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.process.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>process</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.profile.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>profile</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.protocols.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>protocols</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.reduce.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reduce</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.set.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>set</span></div></a></li><li class="depth-2"><a href="ham-fisted.spliterator.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>spliterator</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1>Reductions</h1>
<p>The ham-fisted project extends the concept of Clojure's <code>reduce</code> in a few ways,
taking influence from java streams and Clojure transducers.  The most important
way is a formal definition of a parallel reduction (analogous to <code>pmap</code> for <code>map</code>).</p>
<p>Most interesting is the 3 argument form of <code>(reduce rfn init coll)</code>.  Problems
exist with the 2 argument form <code>(reduce rfn coll)</code> as the reduction function -
<code>rfn</code>'s leftmost argument is sometimes a value from the collection and at other
times an accumulated value.  Some reductions have the property that the
accumulator is in the set of objects in the collection (such as numeric <code>+</code>),
these reductions are not the most general. They are a special case of a
reduction where the accumulator may be a different type entirely than the values
in the collection.</p>
<h2>Parallelizable Containers</h2>
<p>Efficient parallel reductions depend on parallelizable containers.</p>
<p>Java has three types of containers that operate efficiently in parallel.</p>
<ol>
<li>Finite random access containers (ex: an array)</li>
<li>Containers that can provide spliterators (ex: hashtable)</li>
<li>A concatenation of containers suitable for parallel computation over the parts</li>
</ol>
<p>These three types of containers we can parallelize; random access containers,
maps and sets (or more generally anything with a correct spliterator
implementation), and concatenations of sub-containers each of which may not
itself have a parallelizable reduction.</p>
<h2>Parallelized Reduction</h2>
<p>A parallelized reduction works by splitting up elements of the data source.
Many reduction contexts operate simultaneous each of which will perform a serial
reduction.  A separate step merges the results back together.  This may be
thought of as the "true" map-reduce, but either way it may be useful to compare
a parallelized reduction in detail to a serial reduction.</p>
<p>To perform a parallel reduction, four things must be provided:</p>
<ul>
<li><code>init-val-fn</code> - a function to produce initial accumulators for each reduction context</li>
<li><code>rfn</code> - a function that takes an accumulator and a value and updates the accumulator ---  This
is the typical reduction function passed as the first argument to Clojure's <code>reduce</code></li>
<li><code>merge-fn</code> - a function that takes two accumulators and merges them to produces one
result accumulator.</li>
<li><code>coll</code> - a collection of items to reduce to a single output</li>
</ul>
<p>Here are the function signatures (Keep in mind ... <code>preduce</code>:<code>reduce</code> :: <code>pmap</code>:<code>map</code>):</p>
<pre><code class="language-clojure">(defn preduce [init-val-fn rfn merge-fn coll] ...)
</code></pre>
<p>Notably Java streams have a 'collect' method that takes the same four arguments
where the collection is the <code>this</code> object:</p>
<pre><code class="language-java">interface Stream&lt;E&gt; {
&lt;R&gt; R collect(Supplier&lt;R&gt; supplier,
              BiConsumer&lt;R,? super T&gt; accumulator,
              BiConsumer&lt;R,R&gt; combiner);
}
</code></pre>
<p>The parallelizable reduction operates as a a serial reduction if the init-val-fn
is called exactly once with no arguments and the entire collection is passed
along with rfn to reduce:</p>
<pre><code class="language-clojure">(reduce rfn (init-val-fn) coll)
</code></pre>
<p>From there <code>preduce</code> essentially switches on the type of coll and performs one
of four distinct types of reductions:</p>
<ul>
<li>serial</li>
<li>parallel over and index space</li>
<li>parallel over and spliterator space</li>
<li>parallel over sub-containers</li>
</ul>
<h2>Map, Filter, Concat Chains</h2>
<p>It is common in functional programming to implement data transformations as
chains of <code>map</code>, <code>filter</code>, and <code>concat</code> operations.  Analyzing sequences of
these operations is insight with regards to reduction in general and
parallelization of reductions.</p>
<p>The first insight is found in the Clojure transducer pathways and involves collapsing
the reduction function when possible for map and filter applications.  Let's start with
a reduction of the form <code>(-&gt;&gt; coll (map x) (filter y) (reduce ...))</code>.</p>
<p>The filter operator can specialize its reduce implementation by producing a new reduction
function and reducing over its source collection:</p>
<pre><code class="language-java">public Object reduce(IFn rfn, Object init) {
	return source.reduce(new IFn() {
	  public Object invoke(Object acc, Object v) {
	    if(pred.test(v))
		  return rfn.invoke(acc, v);
	    else
		  return acc;
	  }
	}, init);
}
</code></pre>
<p>This results in 'collapsing' the reduction allowing the source to perform the
iteration across its elements and simply dynamically creating a slightly more
complex reduction function, <code>rfn</code>.  A similar pathway exists for <code>map</code> as we can
always delegate up the chain making a slightly more complex reduction function
as long as we are reducing over a single source of data.  This optimization
leads to many fewer function calls and intermediate collections when compared
with naive implementations of <code>map</code> and <code>filter</code>. Clojure's transducers do this
automatically.</p>
<p>Collapsing the reduction also allows us to parallelize reductions like the initial one
stated before as if the filter object has a parallelReduction method that does an identical
collapsing pathway then if the source is parallelizable then the reduction itself can
still parallelize:</p>
<pre><code class="language-java">public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn) {
  return source.parallelReduction(initValFn, new IFn() {...}, mergeFn);
}
</code></pre>
<p>If the source collection itself allows for parallel reduction, then it's
possible to achieve similar 'collapsing' in <code>preduce</code>.  Clojure's transducers do
not have this particular optimization for parallel reduction, but Java streams
do.</p>
<p>Also worth noting, these optimizations are only available if we use the 4
argument form of reduce <em>and</em> if we assume that <code>map</code>, <code>filter</code>, and <code>concat</code> are lazy
and non-caching.</p>
<p>With those assumptions in place it is possible to parallelize a reduction over
the entries, keys or values of map using simple primitive composition:</p>
<pre><code class="language-clojure">user&gt; (require '[ham-fisted.api :as hamf])
nil
user&gt; (require '[ham-fisted.lazy-noncaching :as lznc])
nil
user&gt; (def data (hamf/immut-map (lznc/map #(vector % %) (range 20000))))
#'user/data
user&gt; (type data)
ham_fisted.PersistentHashMap
user&gt; (hamf/preduce + + + (lznc/map key data))
199990000
</code></pre>
<h2>Stream-based Reductions</h2>
<p>Java streams have a notion of parallel reduction built-in. Their design suffers
from two flaws, one minor and one major.</p>
<p>The first minor flaw is that you can ask a stream for a parallel version of
itself and it will give you one if possible else return a copy of itself.
Unfortunately this only works on the first stream in a pipeline so for instance:</p>
<pre><code class="language-java">  coll.stream().map().filter().parallel().collect();
</code></pre>
<p>yields a serial reduction while:</p>
<pre><code class="language-java">  coll.stream().parallel().map().filter().collect();
</code></pre>
<p>yields a parallel reduction.</p>
<p>This is unfortunate because it means you must go back in time to get a parallel
version of the stream if you want to perform a parallel collection; something
that may or may not be easily done at the point in time when you decide you do
in fact want to parallel reduction (especially in library code).</p>
<p>The second and more major flaw is that stream-based parallelization does not
allow the user to pass in their own fork-join pool at any point. This limits use
to the built in pool where it's pad form to park threads or do blocking
operations.</p>
<h2>reducers.clj And Parallel Folds</h2>
<p>Clojure has an alpha namespace that provides a parallel reduction, <a href="https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj">reducers.clj</a>.  The signature
for this method is:</p>
<pre><code class="language-clojure">(defn fold
  "Reduces a collection using a (potentially parallel) reduce-combine
  strategy. The collection is partitioned into groups of approximately
  n (default 512), each of which is reduced with reducef (with a seed
  value obtained by calling (combinef) with no arguments). The results
  of these reductions are then reduced with combinef (default
  reducef). combinef must be associative, and, when called with no
  arguments, (combinef) must produce its identity element. These
  operations may be performed in parallel, but the results will
  preserve order."
  {:added "1.5"}
  ([reducef coll] (fold reducef reducef coll))
  ([combinef reducef coll] (fold 512 combinef reducef coll))
  ([n combinef reducef coll]
     (coll-fold coll n combinef reducef)))
</code></pre>
<p>In this case we use overloads of <code>combinef</code> or <code>reducef</code> to provider the initial accumulator
(called the identity element), the rfn, finalization and the merge function.  <code>combinef</code> called
with no arguments provides each thread context's accumulator and called with two arguments
performs a merge of two accumulators.  <code>reducef</code> called with 2 arguments provides
the reduction from a value into the accumulator and when called with one argument
finalizes both the potentially stateful reducing function and finalizes the
accumulator.  It prescribes the parallelization system but users can override a protocol
to do it themselves.</p>
<p>This the same major drawback as the java stream system, namely users cannot provide
their own pool for parallelization.</p>
<p>An interesting decision was made here as to whether one can actually parallelize the
reduction or not.  Transducers, the elements providing <code>reducef</code>, may be stateful
such as <code>(take 15)</code>.  One interesting difference is that state is done with a closure in
the reduction function as opposed to providing a custom accumulator that wraps the user's
accumulator but tracks state.</p>
<p>One aspect we haven't discussed but that is also handled here in an interesting
manner is that whether a reduction can be parallelized or not is a function both
of the container <em>and</em> of the reducer.  <code>reducers.clj</code> does a sort of
double-dispatch where the transducer may choose to implement the parallel
reduction, called <code>coll-fold</code> or not and is queried first and if it allows
parallel reduction then the collection itself is dispatched.  Overall this is a
great, safe choice because it disallows completely parallel dispatch if the
transducer or the collection do not support it.</p>
<h2>Parallel Reducers</h2>
<p>If we combine all three functions: <code>init-val-fn</code>, <code>rfn</code>, and <code>merge-fn</code> into one object
then we get a ParallelReducer, defined in protocols.clj.  This protocol allows the
user to pass a single object into a parallelized reduction as opposed to three functions
which is useful when we want to have many reducers reduce over a single source of data.
A <code>finalize</code> method is added in order to allow compositions of reducers, and to allow
reducers to hide state and information from end users:</p>
<pre><code class="language-clojure">(defprotocol ParallelReducer
  "Parallel reducers are simple a single object that you can pass into preduce as
  opposed to 3 separate functions."
  (-&gt;init-val-fn [item]
    "Returns the initial values for a parallel reduction.  This function
takes no arguments and returns the initial reduction value.")
  (-&gt;rfn [item]
    "Returns the reduction function for a parallel reduction. This function takes
two arguments, the initial value and a value from the collection and returns a new
initial value.")
  (-&gt;merge-fn [item]
    "Returns the merge function for a parallel reduction.  This function takes
two initial values and returns a new initial value.")
  (finalize [item v]
    "A finalize function called on the result of the reduction after it is
reduced but before it is returned to the user.  Identity is a reasonable default."))
</code></pre>
<p>There are defaults to the reducer protocol for an IFn which assumes it can be
called with no arguments for a initial value and two arguments for both
reduction and merge.  This works for things like <code>+</code> and <code>*</code>.  Additionally
there are implementations provided for the ham_fisted Sum (Kahans compensated)
and SimpleSum
<a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/DoubleConsumer.html">DoubleConsumer</a>
classes.</p>
<p>With the three functions bundled into one logical protocol or object it is easy then
to create complex (aggregate) and efficient parallelized reductions:</p>
<pre><code class="language-clojure">user&gt; (require '[ham-fisted.reduce :as hamf-rf])
nil
user&gt; (hamf-rf/preduce-reducers {:sum + :product *} (range 1 20))
{:product 121645100408832000, :sum 190}
user&gt;
</code></pre>
<p>This goes over the data in parallel, exactly once.</p>
<h2>Consumers, Transducers, and <code>rfn</code> Chains</h2>
<p>If we look at the reduction in terms of a push model as opposed to a pull model
where the stream will push data into a consumer then we can implement similar
chains or map and filter.  These are based on creating a new consumer that takes
the older consumer and the filter predicate or mapping function.  In this way
one can implement a pipeline on the input stream, or perhaps diverging pipelines
on each reduction function in a multiple reducer scenario.  Since the init and
merge functions operate in accumulator space, which remains unchanged, one can
develop up increasingly sophisticated reduction functions and still perform a
parallelized reduction.  Naturally, everything is composed in reverse (push
instead of pull), which is the reason that <code>comp</code> works in reverse when working
with transducers.</p>
<p>In fact, given that the covers are pulled back on composing reduction functions,
the definition of the single argument <code>clojure.core/filter</code> becomes more clear:</p>
<pre><code class="language-clojure">(defn filter
  "Returns a lazy sequence of the items in coll for which
  (pred item) returns logical true. pred must be free of side-effects.
  Returns a transducer when no collection is provided."
  {:added "1.0"
   :static true}
  ([pred]
    (fn [rf]
      (fn
        ([] (rf))
        ([result] (rf result))
        ([result input]
           (if (pred input)
             (rf result input)
             result)))))))
</code></pre>
<p>It returns a function that, when given a reduction function, returns a new reduction
function that when called in the two argument form is identical to the result above
(although expressed in pure Clojure as opposed to Java).</p>
<p>Starting with the concept that a reduction begins at the collection, flows
downward through the pipeline and bottoms out at the reducer then the
lazy-noncaching namespace and Java streams implement parallelization flowing
from the container downward. Separately consumer chains and transducers
implement the pipeline flowing up from the reducer itself.  Thus building the
pipeline either downward from the source or upward from the final reduction
produces subtly different properties.  Regardless, every system must disable
parallelization where it will cause an incorrect answer (to ensure correctness)</p>
<ul>
<li>such as in a stateful transducer.</li>
</ul>
<p>Broadly speaking, however, it can be faster to enable full parallelization and
filter invalid results than it is to force an early serialization our problem
and thus lose lots of our parallelization potential.  When concerned with
performance, attempt to move transformations as much as possible into a
parallelizable domain.</p>
<p>For the <code>take-n</code> use case specifically mentioned above and potentially for others we
can parallelize the reduction and do the take-n both in the parallelized phase and
in the merge phase assuming we are using an ordered parallelization, so that doesn't
itself necessarily force a serialized reduction but there are of course
transformations and reductions that do.  There are intermediate points however that are
perhaps somewhat wasteful in terms of cpu load but do allow for more parallelization - a
tradeoff that is sometimes worth it. Generically speaking we can visualize this sort
of a tradeoff as triangle of three points where one point is data locality, one
point parallelism, and one point redundancy.  Specifically if we are willing to
trade some cpu efficiency for some redundancy, for instance, then we often get more
parallelization.  Likewise if we are willing to save/load data from 'far' away from
the CPU, then we can cut down on redundancy but at the cost of locality.  For more
on this line of thinking please take a moment and read at least some of Jonathan Ragan-Kelly's
<a href="http://people.csail.mit.edu/jrk/jrkthesis.pdf">excellent PhD thesis</a> - a better explanation
of the above line of reasoning begins on page 20.</p>
<h2>Primitive Typed Serial Reductions</h2>
<p>This comes last for a good reason :-) - it doesn't make a huge difference in performance
but it should be noted allowing objects to implemented typed reductions:</p>
<pre><code class="language-java">default Object doubleReduction(IFn.ODO op, Object init);
default Object longReduction(IFn.OLO op, Object init)
</code></pre>
<p>where the next incoming value is a primitive object but the accumulator is still
a generic object allows us to use things like <code>DoubleConsumers</code> and
<code>LongConsumers</code> and avoid boxing the stream.  Furthermore if the aforementioned
<code>map</code> and <code>filter</code> primitives are careful about their rfn composition we can
maintain a completely primitive typed pipeline through an entire processing
chain.</p>
<h2>One Final Note About Performance</h2>
<p>Collapsing reductions brings the source iteration pathway closer to the final
reduction pathway in terms of machine stack space which allows HotSpot to
optimize the entire chain more readily.  Regardless of how good HotSpot gets,
however, parallelizing will nearly always result in a larger win but both work
together to enable peak performance on the JVM given arbitrary partially typed
compositions of sequences and reductions.</p>
<p>When increasing the data size yet again, one can of course use the same design
to distribute the computations to different machines.  As some people have
figured out, however, simply implementing the transformations you need
efficiently reduces or completely eliminates the need to distribute computation
in the first place leading to a simpler, easier to test and more robust system.</p>
<p>Ideally we can make achieving great performance for various algorithms clear and easy and
thus avoid myriad of issues regarding distributing computing in the first place.</p>
<ul>
<li>The first rule of distributed systems is to avoid distributing your computation in the first place - <a href="https://bravenewgeek.com/service-disoriented-architecture/">1</a>, <a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing">2</a>.</li>
<li>The first law of distributed objects is to avoid using distributed objects. <a href="https://martinfowler.com/bliki/FirstLaw.html">3</a>.</li>
</ul>
</div></div></div></body></html>

================================================
FILE: docs/css/default.css
================================================
@import url('https://fonts.googleapis.com/css?family=PT+Sans');

body {
    font-family: 'PT Sans', Helvetica, sans-serif;
    font-size: 14px;
}

a {
    color: #337ab7;
    text-decoration: none;
}

a:hover {
    color: #30426a;
    text-decoration: underline;
}

pre, code {
    font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
    font-size: 9pt;
    margin: 15px 0;
}

h1 {
    font-weight: normal;
    font-size: 29px;
    margin: 10px 0 2px 0;
    padding: 0;
}

h2 {
    font-weight: normal;
    font-size: 25px;
}

h3 > a:hover {
    text-decoration: none;
}

.document h1, .namespace-index h1 {
    font-size: 32px;
    margin-top: 12px;
}

#header, #content, .sidebar {
    position: fixed;
}

#header {
    top: 0;
    left: 0;
    right: 0;
    height: 22px;
    color: #f5f5f5;
    padding: 5px 7px;
}

#content {
    top: 32px;
    right: 0;
    bottom: 0;
    overflow: auto;
    background: #fff;
    color: #333;
    padding: 0 18px;
}

.sidebar {
    position: fixed;
    top: 32px;
    bottom: 0;
    overflow: auto;
}

.sidebar.primary {
    background: #30426a;
    border-right: solid 1px #cccccc;
    left: 0;
    width: 250px;
    color: white;
    font-size: 110%;
}

.sidebar.secondary {
    background: #f2f2f2;
    border-right: solid 1px #d7d7d7;
    left: 251px;
    width: 200px;
    font-size: 110%;
}

#content.namespace-index, #content.document {
    left: 251px;
}

#content.namespace-docs {
    left: 452px;
}

#content.document {
    padding-bottom: 10%;
}

#header {
    background: #2d3e63;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
    z-index: 100;
}

#header h1 {
    margin: 0;
    padding: 0;
    font-size: 18px;
    font-weight: lighter;
    text-shadow: -1px -1px 0px #333;
}

#header h1 .project-version {
    font-weight: normal;
}

.project-version {
    padding-left: 0.15em;
}

#header a, .sidebar a {
    display: block;
    text-decoration: none;
}

#header a {
    color: #f5f5f5;
}

.sidebar.primary, .sidebar.primary a {
    color: #b2bfdc;
}

.sidebar.primary a:hover {
    color: white;
}

.sidebar.secondary, .sidebar.secondary a {
    color: #738bc0;
}

.sidebar.secondary a:hover {
    color: #2d3e63;
}

#header h2 {
    float: right;
    font-size: 9pt;
    font-weight: normal;
    margin: 4px 3px;
    padding: 0;
    color: #bbb;
}

#header h2 a {
    display: inline;
}

.sidebar h3 {
    margin: 0;
    padding: 10px 13px 0 13px;
    font-size: 19px;
    font-weight: lighter;
}

.sidebar.primary h3.no-link {
    text-transform: uppercase;
    font-size: 12px;
    color: #738bc0;
}

.sidebar.secondary h3 a {
    text-transform: uppercase;
    font-size: 12px;
    color: #2d3e63;
}

.sidebar ul {
    padding: 7px 0 6px 0;
    margin: 0;
}

.sidebar ul.index-link {
    padding-bottom: 4px;
}

.sidebar li {
    display: block;
    vertical-align: middle;
}

.sidebar li a, .sidebar li .no-link {
    border-left: 3px solid transparent;
    padding: 0 10px;
    white-space: nowrap;
}

.sidebar li .inner {
    display: inline-block;
    padding-top: 7px;
    height: 24px;
}

.sidebar li a, .sidebar li .tree {
    height: 31px;
}

.depth-1 .inner { padding-left: 2px; }
.depth-2 .inner { padding-left: 6px; }
.depth-3 .inner { padding-left: 20px; }
.depth-4 .inner { padding-left: 34px; }
.depth-5 .inner { padding-left: 48px; }
.depth-6 .inner { padding-left: 62px; }

.sidebar li .tree {
    display: block;
    float: left;
    position: relative;
    top: -10px;
    margin: 0 4px 0 0;
    padding: 0;
}

.sidebar li.depth-1 .tree {
    display: none;
}

.sidebar li .tree .top, .sidebar li .tree .bottom {
    display: block;
    margin: 0;
    padding: 0;
    width: 7px;
}

.sidebar li .tree .top {
    border-left: 1px solid #aaa;
    border-bottom: 1px solid #aaa;
    height: 19px;
}

.sidebar li .tree .bottom {
    height: 22px;
}

.sidebar li.branch .tree .bottom {
    border-left: 1px solid #aaa;
}

.sidebar.primary li.current a {
    border-left: 3px solid #e99d1a;
    color: white;
}

.sidebar.secondary li.current a {
    border-left: 3px solid #2d3e63;
    color: #33a;
}

.namespace-index h2 {
    margin: 30px 0 0 0;
}

.namespace-index h3 {
    font-size: 16px;
    font-weight: bold;
    margin-bottom: 0;
    letter-spacing: 0.05em;
    border-bottom: solid 1px #ddd;
    max-width: 680px;
    background-color: #fafafa;
    padding: 0.5em;
}

.namespace-index .topics {
    padding-left: 30px;
    margin: 11px 0 0 0;
}

.namespace-index .topics li {
    padding: 5px 0;
}

.namespace-docs h3 {
    font-size: 18px;
    font-weight: bold;
}

.public h3 {
    margin: 0;
    float: left;
}

.usage {
    clear: both;
}

.public {
    margin: 0;
    border-top: 1px solid #e0e0e0;
    padding-top: 14px;
    padding-bottom: 6px;
}

.public:last-child {
    margin-bottom: 20%;
}

.members .public:last-child {
    margin-bottom: 0;
}

.members {
    margin: 15px 0;
}

.members h4 {
    color: #555;
    font-weight: normal;
    font-variant: small-caps;
    margin: 0 0 5px 0;
}

.members .inner {
    padding-top: 5px;
    padding-left: 12px;
    margin-top: 2px;
    margin-left: 7px;
    border-left: 1px solid #bbb;
}

#content .members .inner h3 {
    font-size: 12pt;
}

.members .public {
    border-top: none;
    margin-top: 0;
    padding-top: 6px;
    padding-bottom: 0;
}

.members .public:first-child {
    padding-top: 0;
}

h4.type,
h4.dynamic,
h4.added,
h4.deprecated {
    float: left;
    margin: 3px 10px 15px 0;
    font-size: 15px;
    font-weight: bold;
    font-variant: small-caps;
}

.public h4.type,
.public h4.dynamic,
.public h4.added,
.public h4.deprecated {
    font-size: 13px;
    font-weight: bold;
    margin: 3px 0 0 10px;
}

.members h4.type,
.members h4.added,
.members h4.deprecated {
    margin-top: 1px;
}

h4.type {
    color: #717171;
}

h4.dynamic {
    color: #9933aa;
}

h4.added {
    color: #508820;
}

h4.deprecated {
    color: #880000;
}

.namespace {
    margin-bottom: 30px;
}

.namespace:last-child {
    margin-bottom: 10%;
}

.index {
    padding: 0;
    font-size: 80%;
    margin: 15px 0;
    line-height: 1.6em;
}

.index * {
    display: inline;
}

.index p {
    padding-right: 3px;
}

.index li {
    padding-right: 5px;
}

.index ul {
    padding-left: 0;
}

.type-sig {
    clear: both;
    color: #088;
}

.type-sig pre {
    padding-top: 10px;
    margin: 0;
}

.usage code {
    display: block;
    color: #008;
    margin: 2px 0;
}

.usage code:first-child {
    padding-top: 10px;
}

p {
    margin: 15px 0;
}

.public p:first-child, .public pre.plaintext {
    margin-top: 12px;
}

.doc {
    margin: 0 0 26px 0;
    clear: both;
}

.public .doc {
    margin: 0;
}

.namespace-index {
  font-size: 120%;
}

.namespace-index .doc {
    margin-bottom: 20px;
}

.namespace-index .namespace .doc {
    margin-bottom: 10px;
}

.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {
    line-height: 1.6em;
}

.markdown h2 {
    font-weight: normal;
    font-size: 25px;
}

#content .markdown h3 {
    font-size: 20px;
}

.markdown h4 {
    font-size: 15px;
}

.doc, .public, .namespace .index {
    max-width: 680px;
    overflow-x: visible;
}

.markdown pre > code {
    display: block;
    padding: 10px;
}

.markdown pre > code, .src-link a {
    border: 1px solid #e4e4e4;
    border-radius: 2px;
}

.src-link a {
    background: #f6f6f6;
}

.markdown code:not(.hljs) {
    color: #c7254e;
    background-color: #f9f2f4;
    border-radius: 4px;
    font-size: 90%;
    padding: 2px 4px;
}

pre.deps {
    display: inline-block;
    margin: 0 10px;
    border: 1px solid #e4e4e4;
    border-radius: 2px;
    padding: 10px;
    background-color: #f6f6f6;
}

.markdown hr {
    border-style: solid;
    border-top: none;
    color: #ccc;
}

.doc ul, .doc ol {
    padding-left: 30px;
}

.doc table {
    border-collapse: collapse;
    margin: 0 10px;
}

.doc table td, .doc table th {
    border: 1px solid #dddddd;
    padding: 4px 6px;
}

.doc table th {
    background: #f2f2f2;
}

.doc dl {
    margin: 0 10px 20px 10px;
}

.doc dl dt {
    font-weight: bold;
    margin: 0;
    padding: 3px 0;
    border-bottom: 1px solid #ddd;
}

.doc dl dd {
    padding: 5px 0;
    margin: 0 0 5px 10px;
}

.doc abbr {
    border-bottom: 1px dotted #333;
    font-variant: none;
    cursor: help;
}

.src-link {
    margin-bottom: 15px;
}

.src-link a {
    font-size: 70%;
    padding: 1px 4px;
    text-decoration: none;
    color: #5555bb;
    background-color: #f6f6f6;
}

blockquote {
    opacity: 0.6;
    border-left: solid 2px #ddd;
    margin-left: 0;
    padding-left: 1em;
}

/* Responsiveness Theme */

@media (max-device-width: 480px) {
  .sidebar {
    display:none;
  }

  #content {
    position: relative;
    left: initial !important;
    top: 110px;
    padding: 0 1em;
  }

  #header {
    display: flex;
    flex-direction: column-reverse;
    height: 100px;
  }

  #header > h1 {
    font-size: 52px;
  }

  #header h2 {
    float: none;
    font-size: 20px;
  }

  .namespace-index > h1 {
    display: none;
  }

  .public, .doc, .namespace > .index, .namespace > .doc, .namespace > h3 {
    max-width: initial;
  }

  .doc {
    text-align: justify;
  }

  .public {
    padding-top: 2em;
    padding-bottom: 2em;
  }

  .public > h3 {
    font-size: 300%;
  }

  .public > h4.type, .public > h4.added, .public > h4.deprecated {
    font-size: 150%;
    margin-top: 1em;
  }

  pre > code {
    font-size: 200%;
  }
}


================================================
FILE: docs/ham-fisted.api.html
================================================
<!DOCTYPE html PUBLIC ""
    "">
<html><head><meta charset="UTF-8" /><title>ham-fisted.api documentation</title><script async="true" src="https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM"></script><script>window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-XJYNJF48RM');</script><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="highlight/solarized-light.css" /><script type="text/javascript" src="highlight/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a> with <a href="https://github.com/xsc/codox-theme-rdash">RDash UI</a> theme</h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Ham-Fisted</span> <span class="project-version">3.029</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="Reductions.html"><div class="inner"><span>Reductions</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>ham-fisted</span></div></div></li><li class="depth-2 branch current"><a href="ham-fisted.api.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>api</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.bloom-filter.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bloom-filter</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.defprotocol.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>defprotocol</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.fjp.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>fjp</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.function.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>function</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.hlet.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>hlet</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.iterator.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>iterator</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.lazy-noncaching.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>lazy-noncaching</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.mut-map.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mut-map</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.primitive-invoke.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>primitive-invoke</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.process.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>process</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.profile.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>profile</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.protocols.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>protocols</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.reduce.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reduce</span></div></a></li><li class="depth-2 branch"><a href="ham-fisted.set.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>set</span></div></a></li><li class="depth-2"><a href="ham-fisted.spliterator.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>spliterator</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="ham-fisted.api.html#var--.3Ecollection"><div class="inner"><span>-&gt;collection</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var--.3Erandom-access"><div class="inner"><span>-&gt;random-access</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var--.3Ereducible"><div class="inner"><span>-&gt;reducible</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-add-all.21"><div class="inner"><span>add-all!</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-add-constant.21"><div class="inner"><span>add-constant!</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-apply-concat"><div class="inner"><span>apply-concat</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-apply-concatv"><div class="inner"><span>apply-concatv</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-argsort"><div class="inner"><span>argsort</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-array-list"><div class="inner"><span>array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-assoc.21"><div class="inner"><span>assoc!</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-binary-search"><div class="inner"><span>binary-search</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-boolean-array"><div class="inner"><span>boolean-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-boolean-array-list"><div class="inner"><span>boolean-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-byte-array"><div class="inner"><span>byte-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-byte-array-list"><div class="inner"><span>byte-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-char-array"><div class="inner"><span>char-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-char-array-list"><div class="inner"><span>char-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-clear.21"><div class="inner"><span>clear!</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-clear-memoized-fn.21"><div class="inner"><span>clear-memoized-fn!</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-complement"><div class="inner"><span>complement</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-concata"><div class="inner"><span>concata</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-concatv"><div class="inner"><span>concatv</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-cond"><div class="inner"><span>cond</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-conj.21"><div class="inner"><span>conj!</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-constant-count"><div class="inner"><span>constant-count</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-constant-countable.3F"><div class="inner"><span>constant-countable?</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-constantly"><div class="inner"><span>constantly</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-count"><div class="inner"><span>count</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-custom-counted-ireduce"><div class="inner"><span>custom-counted-ireduce</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-custom-ireduce"><div class="inner"><span>custom-ireduce</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-darange"><div class="inner"><span>darange</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-dbl-ary-cls"><div class="inner"><span>dbl-ary-cls</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-difference"><div class="inner"><span>difference</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-dnth"><div class="inner"><span>dnth</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-double-array"><div class="inner"><span>double-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-double-array-list"><div class="inner"><span>double-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-drop"><div class="inner"><span>drop</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-drop-last"><div class="inner"><span>drop-last</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-drop-min"><div class="inner"><span>drop-min</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-dsummary"><div class="inner"><span>dsummary</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-dvec"><div class="inner"><span>dvec</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-empty-map"><div class="inner"><span>empty-map</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-empty-set"><div class="inner"><span>empty-set</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-empty-vec"><div class="inner"><span>empty-vec</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-empty.3F"><div class="inner"><span>empty?</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-evict-memoized-call"><div class="inner"><span>evict-memoized-call</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-filterv"><div class="inner"><span>filterv</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-first"><div class="inner"><span>first</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-float-array"><div class="inner"><span>float-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-float-array-list"><div class="inner"><span>float-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-fnth"><div class="inner"><span>fnth</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-freq-reducer"><div class="inner"><span>freq-reducer</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-frequencies"><div class="inner"><span>frequencies</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-fvec"><div class="inner"><span>fvec</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-group-by"><div class="inner"><span>group-by</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-group-by-consumer"><div class="inner"><span>group-by-consumer</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-group-by-reduce"><div class="inner"><span>group-by-reduce</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-group-by-reducer"><div class="inner"><span>group-by-reducer</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-hash-map"><div class="inner"><span>hash-map</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-iarange"><div class="inner"><span>iarange</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-immut-list"><div class="inner"><span>immut-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-immut-map"><div class="inner"><span>immut-map</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-immut-set"><div class="inner"><span>immut-set</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-in-fork-join-task.3F"><div class="inner"><span>in-fork-join-task?</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-inc-consumer"><div class="inner"><span>inc-consumer</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-inc-consumer-reducer"><div class="inner"><span>inc-consumer-reducer</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-int-array"><div class="inner"><span>int-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-int-array-list"><div class="inner"><span>int-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-intersect-sets"><div class="inner"><span>intersect-sets</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-intersection"><div class="inner"><span>intersection</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-inth"><div class="inner"><span>inth</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-into"><div class="inner"><span>into</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-into-array"><div class="inner"><span>into-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-ivec"><div class="inner"><span>ivec</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-java-concurrent-hashmap"><div class="inner"><span>java-concurrent-hashmap</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-java-hashmap"><div class="inner"><span>java-hashmap</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-java-hashset"><div class="inner"><span>java-hashset</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-java-linked-hashmap"><div class="inner"><span>java-linked-hashmap</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-keys"><div class="inner"><span>keys</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-larange"><div class="inner"><span>larange</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-last"><div class="inner"><span>last</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-linear-merge-iterable"><div class="inner"><span>linear-merge-iterable</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-lines"><div class="inner"><span>lines</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-linked-hashmap"><div class="inner"><span>linked-hashmap</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-lnth"><div class="inner"><span>lnth</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-long-array"><div class="inner"><span>long-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-long-array-list"><div class="inner"><span>long-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-lsum"><div class="inner"><span>lsum</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-lsummary"><div class="inner"><span>lsummary</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-lvec"><div class="inner"><span>lvec</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-make-map-entry"><div class="inner"><span>make-map-entry</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-map-intersection"><div class="inner"><span>map-intersection</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-map-union"><div class="inner"><span>map-union</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-map-union-java-hashmap"><div class="inner"><span>map-union-java-hashmap</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mapmap"><div class="inner"><span>mapmap</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mapv"><div class="inner"><span>mapv</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mean"><div class="inner"><span>mean</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-memoize"><div class="inner"><span>memoize</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-memoize-cache-as-map"><div class="inner"><span>memoize-cache-as-map</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-merge"><div class="inner"><span>merge</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-merge-iterator"><div class="inner"><span>merge-iterator</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-merge-with"><div class="inner"><span>merge-with</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mmax-idx"><div class="inner"><span>mmax-idx</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mmax-key"><div class="inner"><span>mmax-key</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mmin-idx"><div class="inner"><span>mmin-idx</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mmin-key"><div class="inner"><span>mmin-key</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mode"><div class="inner"><span>mode</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mut-hashtable-map"><div class="inner"><span>mut-hashtable-map</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mut-list"><div class="inner"><span>mut-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mut-long-hashtable-map"><div class="inner"><span>mut-long-hashtable-map</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mut-long-map"><div class="inner"><span>mut-long-map</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mut-map"><div class="inner"><span>mut-map</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mut-map-rf"><div class="inner"><span>mut-map-rf</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mut-map-union.21"><div class="inner"><span>mut-map-union!</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mut-set"><div class="inner"><span>mut-set</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-mutable-map.3F"><div class="inner"><span>mutable-map?</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-not"><div class="inner"><span>not</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-obj-ary"><div class="inner"><span>obj-ary</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-object-array"><div class="inner"><span>object-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-object-array-list"><div class="inner"><span>object-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-ovec"><div class="inner"><span>ovec</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-persistent.21"><div class="inner"><span>persistent!</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-pgroups"><div class="inner"><span>pgroups</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-pmap"><div class="inner"><span>pmap</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-pmap-io"><div class="inner"><span>pmap-io</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-pmap-opts"><div class="inner"><span>pmap-opts</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-range"><div class="inner"><span>range</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-re-matches"><div class="inner"><span>re-matches</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-reduced-.3E"><div class="inner"><span>reduced-&gt;</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-reindex"><div class="inner"><span>reindex</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-repeat"><div class="inner"><span>repeat</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-rest"><div class="inner"><span>rest</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-reverse"><div class="inner"><span>reverse</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-short-array"><div class="inner"><span>short-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-short-array-list"><div class="inner"><span>short-array-list</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-shuffle"><div class="inner"><span>shuffle</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-sort"><div class="inner"><span>sort</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-sort-by"><div class="inner"><span>sort-by</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-sorta"><div class="inner"><span>sorta</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-splice"><div class="inner"><span>splice</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-subvec"><div class="inner"><span>subvec</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-sum"><div class="inner"><span>sum</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-sum-fast"><div class="inner"><span>sum-fast</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-sum-stable-nelems"><div class="inner"><span>sum-stable-nelems</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-take"><div class="inner"><span>take</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-take-last"><div class="inner"><span>take-last</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-take-min"><div class="inner"><span>take-min</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-transient"><div class="inner"><span>transient</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-transient-map-rf"><div class="inner"><span>transient-map-rf</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-union"><div class="inner"><span>union</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-union-reduce-maps"><div class="inner"><span>union-reduce-maps</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-update-vals"><div class="inner"><span>update-vals</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-update-values"><div class="inner"><span>update-values</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-upgroups"><div class="inner"><span>upgroups</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-upmap"><div class="inner"><span>upmap</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-vals"><div class="inner"><span>vals</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-vec"><div class="inner"><span>vec</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-vector"><div class="inner"><span>vector</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-wrap-array"><div class="inner"><span>wrap-array</span></div></a></li><li class="depth-1"><a href="ham-fisted.api.html#var-wrap-array-growable"><div class="inner"><span>wrap-array-growable</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">ham-fisted.api</h1><div class="doc"><div class="markdown"><p>Fast mutable and immutable associative data structures based on bitmap trie
hashmaps. Mutable pathways implement the <code>java.util.Map</code> or <code>Set</code> interfaces
including in-place update features such as compute or computeIfPresent.</p>
<p>Mutable maps or sets can be turned into their immutable counterparts via the
Clojure <code>persistent!</code> call. This allows working in a mutable space for
convenience and performance then switching to an immutable pathway when
necessary. Note: after <code>persistent!</code> one should never backdoor mutate map or
set again as this will break the contract of immutability.  Immutable
data structures also support conversion to transient via <code>transient</code>.</p>
<p>Map keysets (<code>.keySet</code>) are full <code>PersistentHashSet</code>s of keys.</p>
<p>Maps and sets support metadata but setting the metadata on mutable objects
returns a new mutable object that shares the backing store leading to possible
issues. Metadata is transferred to the persistent versions of the
mutable/transient objects upon <code>persistent!</code>.</p>
<p>Very fast versions of union, difference and intersection are provided for maps
and sets with the map version of union and difference requiring an extra
argument, a <code>java.util.BiFunction</code> or an <code>IFn</code> taking 2 arguments to merge the
left and right sides into the final map. These implementations of union,
difference, and intersection are the fastest implementation of these
operations we know of on the JVM.</p>
<p>Additionally a fast value update pathway is provided, enabling quickly
updating all the values in a given map. Additionally, a new map primitive</p>
<ul>
<li><a href="ham-fisted.api.html#var-mapmap">mapmap</a> - allows transforming a given map into a new map quickly by
mapping across all the entries.</li>
</ul>
<p>Unlike the standard Java objects, mutation-via-iterator is not supported.</p>
</div></div><div class="public anchor" id="var--.3Ecollection"><h3>-&gt;collection</h3><div class="usage"><code>(-&gt;collection item)</code></div><div class="doc"><div class="markdown"><p>Ensure item is an implementation of java.util.Collection.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L144">view source</a></div></div><div class="public anchor" id="var--.3Erandom-access"><h3>-&gt;random-access</h3><div class="usage"><code>(-&gt;random-access item)</code></div><div class="doc"><div class="markdown"><p>Ensure item is derived from java.util.List and java.util.RandomAccess and
thus supports constant time random addressing.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L150">view source</a></div></div><div class="public anchor" id="var--.3Ereducible"><h3>-&gt;reducible</h3><div class="usage"><code>(-&gt;reducible item)</code></div><div class="doc"><div class="markdown"><p>Ensure item either implements IReduceInit or java.util.Collection.  For arrays
this will return an object that has a much more efficient reduction pathway
than the base Clojure reducer.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L157">view source</a></div></div><div class="public anchor" id="var-add-all.21"><h3>add-all!</h3><div class="usage"><code>(add-all! l1 l2)</code></div><div class="doc"><div class="markdown"><p>Add all items from l2 to l1.  l1 is expected to be a java.util.List implementation.
Returns l1.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L684">view source</a></div></div><div class="public anchor" id="var-add-constant.21"><h3>add-constant!</h3><div class="usage"><code>(add-constant! l idx v)</code><code>(add-constant! l idx count v)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2152">view source</a></div></div><div class="public anchor" id="var-apply-concat"><h3>apply-concat</h3><div class="usage"><code>(apply-concat args)</code></div><div class="doc"><div class="markdown"><p>Faster lazy noncaching version of (apply concat)</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1612">view source</a></div></div><div class="public anchor" id="var-apply-concatv"><h3>apply-concatv</h3><div class="usage"><code>(apply-concatv data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1570">view source</a></div></div><div class="public anchor" id="var-argsort"><h3>argsort</h3><div class="usage"><code>(argsort comp coll)</code><code>(argsort coll)</code></div><div class="doc"><div class="markdown"><p>Sort a collection of data returning an array of indexes.  The collection must be
random access and the return value is an integer array of indexes which will read the
input data in sorted order.  Faster implementations are provided when the collection
is an integer, long, or double array.  See also <a href="ham-fisted.api.html#var-reindex">reindex</a>.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1815">view source</a></div></div><div class="public anchor" id="var-array-list"><h3>array-list</h3><div class="usage"><code>(array-list data)</code><code>(array-list)</code></div><div class="doc"><div class="markdown"><p>Create an implementation of java.util.ArrayList.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L633">view source</a></div></div><div class="public anchor" id="var-assoc.21"><h3>assoc!</h3><div class="usage"><code>(assoc! obj k v)</code></div><div class="doc"><div class="markdown"><p>assoc! that works on transient collections, implementations of java.util.Map and
RandomAccess java.util.List implementations.  Be sure to keep track of return value
as some implementations return a different return value than the first argument.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L642">view source</a></div></div><div class="public anchor" id="var-binary-search"><h3>binary-search</h3><div class="usage"><code>(binary-search coll v)</code><code>(binary-search coll v comp)</code></div><div class="doc"><div class="markdown"><p>Binary search.  Coll must be a sorted random access container.
comp must be an implementation of java.lang.Comparator.  If you know your container's
type, such as a double array, then comp should be a fastutil DoubleComparator.</p>
<p>The most efficient method will be to convert coll to random access using
-&gt;random-access, so for a pure double array it is slightly better to call
-&gt;random-access outside this function before the function call.</p>
<p>This search defaults to the slower java.util.Collections search using
clojure's built in <code>compare</code> - reason being that that allows you to search
for a double number in a vector of only longs.  If you want an accelerated search
you can explicitly pass in a nil comparator <em>but</em> you need to make sure that
you are searching for the rough datatype in the data - e.g. long in a byte array
or a double in a double for float array.  Searching for doubles in integer arrays
with an accelerated search will probably result in confusing results.</p>
<pre><code class="language-clojure">ham-fisted.api&gt; (def data (-&gt;random-access (double-array (range 10))))
#'ham-fisted.api/data
ham-fisted.api&gt; (binary-search data 0)
0
ham-fisted.api&gt; (binary-search data -1)
0
ham-fisted.api&gt; (binary-search data 1)
1
ham-fisted.api&gt; (binary-search data 1.1)
2
ham-fisted.api&gt; (binary-search data 10)
10
ham-fisted.api&gt; (binary-search data 11)
10
ham-fisted.api&gt; ;;be wary of datatype conversions in typed containers
ham-fisted.api&gt; (def data (-&gt;random-access (int-array (range 10))))
#'ham-fisted.api/data
ham-fisted.api&gt; (binary-search data 1)
1
ham-fisted.api&gt; (binary-search data 1.1)
  2
ham-fisted.api&gt; ;;accelerated search - flattens input to container datatype
ham-fisted.api&gt; (binary-search data 1.1 nil)
1
</code></pre>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1706">view source</a></div></div><div class="public anchor" id="var-boolean-array"><h3>boolean-array</h3><div class="usage"><code>(boolean-array)</code><code>(boolean-array data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1938">view source</a></div></div><div class="public anchor" id="var-boolean-array-list"><h3>boolean-array-list</h3><div class="usage"><code>(boolean-array-list)</code><code>(boolean-array-list data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1926">view source</a></div></div><div class="public anchor" id="var-byte-array"><h3>byte-array</h3><div class="usage"><code>(byte-array)</code><code>(byte-array data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1865">view source</a></div></div><div class="public anchor" id="var-byte-array-list"><h3>byte-array-list</h3><div class="usage"><code>(byte-array-list)</code><code>(byte-array-list data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1853">view source</a></div></div><div class="public anchor" id="var-char-array"><h3>char-array</h3><div class="usage"><code>(char-array)</code><code>(char-array data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1919">view source</a></div></div><div class="public anchor" id="var-char-array-list"><h3>char-array-list</h3><div class="usage"><code>(char-array-list)</code><code>(char-array-list data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1907">view source</a></div></div><div class="public anchor" id="var-clear.21"><h3>clear!</h3><div class="usage"><code>(clear! map-or-coll)</code></div><div class="doc"><div class="markdown"><p>Mutably clear a map, set, list or implementation of java.util.Collection.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L695">view source</a></div></div><div class="public anchor" id="var-clear-memoized-fn.21"><h3>clear-memoized-fn!</h3><div class="usage"><code>(clear-memoized-fn! memoized-fn)</code></div><div class="doc"><div class="markdown"><p>Clear a memoized function backing store.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1305">view source</a></div></div><div class="public anchor" id="var-complement"><h3>complement</h3><div class="usage"><code>(complement f)</code></div><div class="doc"><div class="markdown"><p>Like clojure core complement but avoids var lookup on 'not'</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L137">view source</a></div></div><div class="public anchor" id="var-concata"><h3>concata</h3><div class="usage"><code>(concata)</code><code>(concata v1)</code><code>(concata v1 v2)</code><code>(concata v1 v2 &amp; args)</code></div><div class="doc"><div class="markdown"><p>non-lazily concat a set of items returning an object array.  This always returns an
object array an may return an empty array whereas concat may return nil.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1595">view source</a></div></div><div class="public anchor" id="var-concatv"><h3>concatv</h3><div class="usage"><code>(concatv)</code><code>(concatv v1)</code><code>(concatv v1 v2)</code><code>(concatv v1 v2 &amp; args)</code></div><div class="doc"><div class="markdown"><p>non-lazily concat a set of items returning a persistent vector.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1579">view source</a></div></div><div class="public anchor" id="var-cond"><h3>cond</h3><h4 class="type">macro</h4><div class="usage"><code>(cond &amp; clauses)</code></div><div class="doc"><div class="markdown"><p>Similar to <code>core/cond</code> except it supports true else clauses as opposed to always
returning nil on else.  The last clause of an odd number of clauses will be used as
the else branch similar to case.  Additional if the last predicate is the constant
'true' or ':else' it will be used as the else clause.  If no else is provided then
returns nil same as <code>core/cond</code>.</p>
<p>Important! - in order to get correct type hinting on both branches of the if they
both must return an explicit long or double:</p>
<ul>
<li>Sill Boxed</li>
</ul>
<pre><code class="language-clojure">  (defn memory-size
    ^long [a]
    (cond
      (instance? Long a) 24
      :else (.length ^String a) ;;string.length returns integer not long
      ))

(defn memory-size
    ^long [a]
    (cond
      (instance? Long a) 24
      :else (alength ^longs a)
      ))
</code></pre>
<ul>
<li>Correctly Unboxed</li>
</ul>
<pre><code class="language-clojure">(defn memory-size
    ^long [a]
    (cond
      (instance? Long a) 24
      :else (long (.length ^String a))
      ))

(defn memory-size
    ^long [a]
    (cond
      (instance? Long a) 24
      :else (long (alength ^longs a))
      ))
</code></pre>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L212">view source</a></div></div><div class="public anchor" id="var-conj.21"><h3>conj!</h3><div class="usage"><code>(conj! obj val)</code></div><div class="doc"><div class="markdown"><p>conj! that works on transient collections, implementations of java.util.Set and
RandomAccess java.util.List implementations.  Be sure to keep track of return value
as some implementations return a different return value than the first argument.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L658">view source</a></div></div><div class="public anchor" id="var-constant-count"><h3>constant-count</h3><div class="usage"><code>(constant-count data)</code></div><div class="doc"><div class="markdown"><p>Constant time count.  Returns nil if input doesn't have a constant time count.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L413">view source</a></div></div><div class="public anchor" id="var-constant-countable.3F"><h3>constant-countable?</h3><div class="usage"><code>(constant-countable? data)</code></div><div class="doc"><div class="markdown"><p>Return true if data has a constant time count.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L407">view source</a></div></div><div class="public anchor" id="var-constantly"><h3>constantly</h3><div class="usage"><code>(constantly x)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L126">view source</a></div></div><div class="public anchor" id="var-count"><h3>count</h3><div class="usage"><code>(count m)</code></div><div class="doc"><div class="markdown"><p>hamf protocol extensible count</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L142">view source</a></div></div><div class="public anchor" id="var-custom-counted-ireduce"><h3>custom-counted-ireduce</h3><h4 class="type">macro</h4><div class="usage"><code>(custom-counted-ireduce n-elems rfn acc &amp; code)</code></div><div class="doc"><div class="markdown"><p>Custom implementation of IReduceInit and nothing else.  This can be the most efficient
way to pass data to other interfaces.  Also see custom-ireduce if the object
does not need to be counted and see <a href="ham-fisted.api.html#var-reduced-.3E">reduced-&gt;</a> for implementation helper.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2651">view source</a></div></div><div class="public anchor" id="var-custom-ireduce"><h3>custom-ireduce</h3><h4 class="type">macro</h4><div class="usage"><code>(custom-ireduce rfn acc &amp; code)</code></div><div class="doc"><div class="markdown"><p>Custom implementation of IReduceInit and nothing else.  This can be the most efficient
way to pass data to other interfaces.  Also see <a href="ham-fisted.api.html#var-custom-counted-ireduce">custom-counted-ireduce</a> if the object
should also implement ICounted.  See <a href="ham-fisted.api.html#var-reduced-.3E">reduced-&gt;</a> for implementation helper.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2641">view source</a></div></div><div class="public anchor" id="var-darange"><h3>darange</h3><div class="usage"><code>(darange end)</code><code>(darange start end)</code><code>(darange start end step)</code></div><div class="doc"><div class="markdown"><p>Return a double array holding the values of the range.  Use <code>wrap-array</code> to get
an implementation of java.util.List that supports the normal Clojure interfaces.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1787">view source</a></div></div><div class="public anchor" id="var-dbl-ary-cls"><h3>dbl-ary-cls</h3><div class="usage"></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2089">view source</a></div></div><div class="public anchor" id="var-difference"><h3>difference</h3><div class="usage"><code>(difference map1 map2)</code></div><div class="doc"><div class="markdown"><p>Take the difference of two maps (or sets) returning a new map.  Return value is a map1
(or set1) without the keys present in map2.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L871">view source</a></div></div><div class="public anchor" id="var-dnth"><h3>dnth</h3><h4 class="type">macro</h4><div class="usage"><code>(dnth obj idx)</code></div><div class="doc"><div class="markdown"><p>nth operation returning a primitive double.  Efficient when obj is a double array.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2161">view source</a></div></div><div class="public anchor" id="var-double-array"><h3>double-array</h3><h4 class="type">macro</h4><div class="usage"><code>(double-array)</code><code>(double-array data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2105">view source</a></div></div><div class="public anchor" id="var-double-array-list"><h3>double-array-list</h3><div class="usage"><code>(double-array-list)</code><code>(double-array-list cap-or-data)</code></div><div class="doc"><div class="markdown"><p>An array list that is as fast as java.util.ArrayList for add,get, etc but includes
many accelerated operations such as fill and an accelerated addAll when the src data
is an array list.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2077">view source</a></div></div><div class="public anchor" id="var-drop"><h3>drop</h3><div class="usage"><code>(drop n coll)</code></div><div class="doc"><div class="markdown"><p>Drop the first N items of the collection.  If item is random access, the return
value is random-access.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2553">view source</a></div></div><div class="public anchor" id="var-drop-last"><h3>drop-last</h3><div class="usage"><code>(drop-last n)</code><code>(drop-last n coll)</code></div><div class="doc"><div class="markdown"><p>Drop the last N values from a collection.  IF the input is random access,
the result will be random access.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2576">view source</a></div></div><div class="public anchor" id="var-drop-min"><h3>drop-min</h3><div class="usage"><code>(drop-min n comp values)</code><code>(drop-min n values)</code></div><div class="doc"><div class="markdown"><p>Drop the min n values of a collection.  This is not an order-preserving operation.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2564">view source</a></div></div><div class="public anchor" id="var-dsummary"><h3>dsummary</h3><div class="usage"><code>(dsummary data)</code></div><div class="doc"><div class="markdown"><p>Summary statistics {:mean :max :min :n-elems :sum} in double space</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2287">view source</a></div></div><div class="public anchor" id="var-dvec"><h3>dvec</h3><h4 class="type">macro</h4><div class="usage"><code>(dvec)</code><code>(dvec data)</code></div><div class="doc"><div class="markdown"><p>Create a persistent-vector-compatible list backed by a double array.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2112">view source</a></div></div><div class="public anchor" id="var-empty-map"><h3>empty-map</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Constant persistent empty map</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L172">view source</a></div></div><div class="public anchor" id="var-empty-set"><h3>empty-set</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Constant persistent empty set</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L174">view source</a></div></div><div class="public anchor" id="var-empty-vec"><h3>empty-vec</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Constant persistent empty vec</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L176">view source</a></div></div><div class="public anchor" id="var-empty.3F"><h3>empty?</h3><div class="usage"><code>(empty? coll)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1548">view source</a></div></div><div class="public anchor" id="var-evict-memoized-call"><h3>evict-memoized-call</h3><div class="usage"><code>(evict-memoized-call memo-fn fn-args)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1321">view source</a></div></div><div class="public anchor" id="var-filterv"><h3>filterv</h3><div class="usage"><code>(filterv pred coll)</code></div><div class="doc"><div class="markdown"><p>Filter a collection into a vector.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2208">view source</a></div></div><div class="public anchor" id="var-first"><h3>first</h3><div class="usage"><code>(first coll)</code></div><div class="doc"><div class="markdown"><p>Get the first item of a collection.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2298">view source</a></div></div><div class="public anchor" id="var-float-array"><h3>float-array</h3><h4 class="type">macro</h4><div class="usage"><code>(float-array)</code><code>(float-array data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2065">view source</a></div></div><div class="public anchor" id="var-float-array-list"><h3>float-array-list</h3><div class="usage"><code>(float-array-list)</code><code>(float-array-list data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2046">view source</a></div></div><div class="public anchor" id="var-fnth"><h3>fnth</h3><h4 class="type">macro</h4><div class="usage"><code>(fnth obj idx)</code></div><div class="doc"><div class="markdown"><p>nth operation returning a primitive float.  Efficient when obj is a float array.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2173">view source</a></div></div><div class="public anchor" id="var-freq-reducer"><h3>freq-reducer</h3><div class="usage"><code>(freq-reducer options)</code><code>(freq-reducer)</code></div><div class="doc"><div class="markdown"><p>Return a hamf parallel reducer that performs a frequencies operation.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1152">view source</a></div></div><div class="public anchor" id="var-frequencies"><h3>frequencies</h3><div class="usage"><code>(frequencies coll)</code><code>(frequencies options coll)</code></div><div class="doc"><div class="markdown"><p>Faster implementation of clojure.core/frequencies.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1178">view source</a></div></div><div class="public anchor" id="var-fvec"><h3>fvec</h3><h4 class="type">macro</h4><div class="usage"><code>(fvec)</code><code>(fvec data)</code></div><div class="doc"><div class="markdown"><p>Create a persistent-vector-compatible list backed by a float array.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2071">view source</a></div></div><div class="public anchor" id="var-group-by"><h3>group-by</h3><div class="usage"><code>(group-by f options coll)</code><code>(group-by f coll)</code></div><div class="doc"><div class="markdown"><p>Group items in collection by the grouping function f.  Returns persistent map of
keys to persistent vectors.</p>
<p>Options are same as <a href="ham-fisted.api.html#var-group-by-reduce">group-by-reduce</a> but this reductions defaults to an
ordered reduction.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1496">view source</a></div></div><div class="public anchor" id="var-group-by-consumer"><h3>group-by-consumer</h3><div class="usage"><code>(group-by-consumer key-fn reducer coll)</code><code>(group-by-consumer key-fn reducer options coll)</code></div><div class="doc"><div class="markdown"><p>Perform a group-by-reduce passing in a reducer.  Same options as group-by-reduce -
This uses a slightly different pathway - computeIfAbsent - in order to preserve order.
In this case the return value of the reduce fn is ignored.  This allows things like
the linked hash map to preserve initial order of keys.  It map also be slightly
more efficient because the map itself does not need to check the return value
of rfn - something that the <code>.compute</code> primitive <em>does</em> need to do.</p>
<p>Options:</p>
<ul>
<li><code>:skip-finalize?</code> - skip finalization step.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1435">view source</a></div></div><div class="public anchor" id="var-group-by-reduce"><h3>group-by-reduce</h3><div class="usage"><code>(group-by-reduce key-fn init-val-fn rfn merge-fn options coll)</code><code>(group-by-reduce key-fn init-val-fn rfn merge-fn coll)</code></div><div class="doc"><div class="markdown"><p>Group by key. Apply the reduce-fn with the new value an the return of init-val-fn.
Merged maps due to multithreading will be merged with merge-fn in a similar way
of <a href="ham-fisted.protocols.html#var-preduce">preduce</a>.</p>
<p>This type of reduction can be both faster and more importantly use
less memory than a reduction of the forms:</p>
<pre><code class="language-clojure">  (-&gt;&gt; group-by map into)
  ;; or
  (-&gt;&gt; group-by mapmap)
</code></pre>
<p>Options (which are passed to <a href="ham-fisted.protocols.html#var-preduce">preduce</a>):</p>
<ul>
<li><code>:map-fn</code> Function which takes no arguments and must return an instance of
java.util.Map that supports <code>computeIfAbsent</code>.  Some examples:
<ul>
<li><code>(constantly (java.util.concurrent.ConcurrentHashMap. ...))</code>  Very fast update
especially in the case where the keyspace is large.</li>
<li><code>mut-map</code> - Fast merge, fast update, in-place immutable conversion via <code>persistent!</code>.</li>
<li><code>java-hashmap</code> - fast merge, fast update, just a simple java.util.HashMap-based reduction.</li>
<li><code>#(LinkedHashMap.)</code> - When used with options {:ordered? true} the result keys will be
in order <em>and</em> the result values will be reduced in order.</li>
</ul>
</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1348">view source</a></div></div><div class="public anchor" id="var-group-by-reducer"><h3>group-by-reducer</h3><div class="usage"><code>(group-by-reducer key-fn reducer coll)</code><code>(group-by-reducer key-fn reducer options coll)</code></div><div class="doc"><div class="markdown"><p>Perform a group-by-reduce passing in a reducer.  Same options as group-by-reduce.</p>
<p>Options:</p>
<ul>
<li><code>:skip-finalize?</code> - skip finalization step.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1415">view source</a></div></div><div class="public anchor" id="var-hash-map"><h3>hash-map</h3><div class="usage"><code>(hash-map)</code><code>(hash-map a b)</code><code>(hash-map a b c d)</code><code>(hash-map a b c d e f)</code><code>(hash-map a b c d e f g h)</code><code>(hash-map a b c d e f g h i j)</code><code>(hash-map a b c d e f g h i j k l)</code><code>(hash-map a b c d e f g h i j k l m n)</code><code>(hash-map a b c d e f g h i j k l m n o p)</code><code>(hash-map a b c d e f g h i j k l m n o p &amp; args)</code></div><div class="doc"><div class="markdown"><p>Drop-in replacement to Clojure's hash-map function.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L454">view source</a></div></div><div class="public anchor" id="var-iarange"><h3>iarange</h3><div class="usage"><code>(iarange end)</code><code>(iarange start end)</code><code>(iarange start end step)</code></div><div class="doc"><div class="markdown"><p>Return an integer array holding the values of the range.  Use <code>-&gt;collection</code> to get a
list implementation wrapping for generic access.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1767">view source</a></div></div><div class="public anchor" id="var-immut-list"><h3>immut-list</h3><div class="usage"><code>(immut-list)</code><code>(immut-list data)</code></div><div class="doc"><div class="markdown"><p>Create a persistent list.  Object arrays will be treated as if this new object owns them.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L624">view source</a></div></div><div class="public anchor" id="var-immut-map"><h3>immut-map</h3><div class="usage"><code>(immut-map)</code><code>(immut-map data)</code><code>(immut-map options data)</code></div><div class="doc"><div class="markdown"><p>Create an immutable map.  This object supports conversion to a transient map via
Clojure's <code>transient</code> function.  Duplicate keys are treated as if by assoc.</p>
<p>If data is an object array it is treated as a flat key-value list which is distinctly
different than how conj! treats object arrays.  You have been warned.</p>
<p>If you know you will have consistently more key/val pairs than 8 you should just
use <code>(persistent! (mut-map data))</code> as that avoids the transition from an arraymap
to a persistent hashmap.</p>
<p>Examples:</p>
<pre><code class="language-clojure">ham-fisted.api&gt; (immut-map (obj-ary :a 1 :b 2 :c 3 :d 4))
{:a 1, :b 2, :c 3, :d 4}
ham-fisted.api&gt; (type *1)
ham_fisted.PersistentArrayMap
ham-fisted.api&gt; (immut-map (obj-ary :a 1 :b 2 :c 3 :d 4 :e 5))
{:d 4, :b 2, :c 3, :a 1, :e 5}
ham-fisted.api&gt; (type *1)
ham_fisted.PersistentHashMap
ham-fisted.api&gt; (immut-map [[:a 1][:b 2][:c 3][:d 4][:e 5]])
{:d 4, :b 2, :c 3, :a 1, :e 5}
ham-fisted.api&gt; (type *1)
ham_fisted.PersistentHashMap
</code></pre>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L419">view source</a></div></div><div class="public anchor" id="var-immut-set"><h3>immut-set</h3><div class="usage"><code>(immut-set)</code><code>(immut-set data)</code><code>(immut-set options data)</code></div><div class="doc"><div class="markdown"><p>Create an immutable hashset based on a hash table.  This object supports conversion
to transients via <code>transient</code>.</p>
<p>Options:</p>
<ul>
<li><code>:hash-provider</code> - An implementation of <code>BitmapTrieCommon$HashProvider</code>.  Defaults to
the <a href="default-hash-provider">default-hash-provider</a>.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L587">view source</a></div></div><div class="public anchor" id="var-in-fork-join-task.3F"><h3>in-fork-join-task?</h3><div class="usage"><code>(in-fork-join-task?)</code></div><div class="doc"><div class="markdown"><p>True if you are currently running in a fork-join task</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1021">view source</a></div></div><div class="public anchor" id="var-inc-consumer"><h3>inc-consumer</h3><div class="usage"><code>(inc-consumer)</code><code>(inc-consumer init-value)</code></div><div class="doc"><div class="markdown"><p>Return a consumer that simply increments a long.  See java/ham_fisted/Consumers.java for definition.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2679">view source</a></div></div><div class="public anchor" id="var-inc-consumer-reducer"><h3>inc-consumer-reducer</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>A hamf reducer that works with inc-consumers</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1193">view source</a></div></div><div class="public anchor" id="var-int-array"><h3>int-array</h3><h4 class="type">macro</h4><div class="usage"><code>(int-array)</code><code>(int-array data)</code></div><div class="doc"><div class="markdown"></div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1990">view source</a></div></div><div class="public anchor" id="var-int-array-list"><h3>int-array-list</h3><div class="usage"><code>(int-array-list)</code><code>(int-array-list cap-or-data)</code></div><div class="doc"><div class="markdown"><p>An array list that is as fast as java.util.ArrayList for add,get, etc but includes
many accelerated operations such as fill and an accelerated addAll when the src data
is an array list.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1962">view source</a></div></div><div class="public anchor" id="var-intersect-sets"><h3>intersect-sets</h3><div class="usage"><code>(intersect-sets sets)</code></div><div class="doc"><div class="markdown"><p>Given a sequence of sets, efficiently perform the intersection of them.  This algorithm is usually faster and has a more stable
runtime than (reduce clojure.set/intersection sets) which degrades depending on the order of the sets and the pairwise
intersection of the initial sets.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2446">view source</a></div></div><div class="public anchor" id="var-intersection"><h3>intersection</h3><div class="usage"><code>(intersection s1 s2)</code></div><div class="doc"><div class="markdown"><p>Intersect the keyspace of set1 and set2 returning a new set.  Also works if s1 is a
map and s2 is a set - the map is trimmed to the intersecting keyspace of s1 and s2.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L931">view source</a></div></div><div class="public anchor" id="var-inth"><h3>inth</h3><h4 class="type">macro</h4><div class="usage"><code>(inth obj idx)</code></div><div class="doc"><div class="markdown"><p>nth operation returning a primitive int.  Efficient when obj is an int array.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2179">view source</a></div></div><div class="public anchor" id="var-into"><h3>into</h3><div class="usage"><code>(into container data)</code><code>(into container xform data)</code></div><div class="doc"><div class="markdown"><p>Like clojure.core/into, but also designed to handle editable collections,
transients, and base java.util.Map, List and Set containers.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L259">view source</a></div></div><div class="public anchor" id="var-into-array"><h3>into-array</h3><div class="usage"><code>(into-array aseq)</code><code>(into-array ary-type aseq)</code><code>(into-array ary-type mapfn aseq)</code></div><div class="doc"><div class="markdown"><p>Faster version of clojure.core/into-array.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1625">view source</a></div></div><div class="public anchor" id="var-ivec"><h3>ivec</h3><h4 class="type">macro</h4><div class="usage"><code>(ivec)</code><code>(ivec data)</code></div><div class="doc"><div class="markdown"><p>Create a persistent-vector-compatible list backed by an int array.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2003">view source</a></div></div><div class="public anchor" id="var-java-concurrent-hashmap"><h3>java-concurrent-hashmap</h3><div class="usage"><code>(java-concurrent-hashmap)</code><code>(java-concurrent-hashmap data)</code></div><div class="doc"><div class="markdown"><p>Create a java concurrent hashmap which is still the fastest possible way to solve a
few concurrent problems.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L560">view source</a></div></div><div class="public anchor" id="var-java-hashmap"><h3>java-hashmap</h3><div class="usage"><code>(java-hashmap)</code><code>(java-hashmap data)</code><code>(java-hashmap xform data)</code><code>(java-hashmap xform options data)</code></div><div class="doc"><div class="markdown"><p>Create a java.util.HashMap.  Duplicate keys are treated as if map was created by assoc.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L514">view source</a></div></div><div class="public anchor" id="var-java-hashset"><h3>java-hashset</h3><div class="usage"><code>(java-hashset)</code><code>(java-hashset data)</code></div><div class="doc"><div class="markdown"><p>Create a java hashset which is still the fastest possible way to solve a few problems.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L600">view source</a></div></div><div class="public anchor" id="var-java-linked-hashmap"><h3>java-linked-hashmap</h3><div class="usage"><code>(java-linked-hashmap)</code><code>(java-linked-hashmap data)</code></div><div class="doc"><div class="markdown"><p>Linked hash maps perform identically or very nearly so to java.util.HashMaps
but they retain the order of insertion and modification.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L533">view source</a></div></div><div class="public anchor" id="var-keys"><h3>keys</h3><div class="usage"><code>(keys m)</code></div><div class="doc"><div class="markdown"><p>Return the keys of a map.  This version allows parallel reduction operations on
the returned sequence.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L728">view source</a></div></div><div class="public anchor" id="var-larange"><h3>larange</h3><div class="usage"><code>(larange end)</code><code>(larange start end)</code><code>(larange start end step)</code></div><div class="doc"><div class="markdown"><p>Return a long array holding values of the range.  Use <code>-&gt;collection</code> get a list
implementation for generic access.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1777">view source</a></div></div><div class="public anchor" id="var-last"><h3>last</h3><div class="usage"><code>(last coll)</code></div><div class="doc"><div class="markdown"><p>Get the last item in the collection.  Constant time for
random access lists.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2310">view source</a></div></div><div class="public anchor" id="var-linear-merge-iterable"><h3>linear-merge-iterable</h3><div class="usage"><code>(linear-merge-iterable cmp pred iterables)</code><code>(linear-merge-iterable cmp iterables)</code><code>(linear-merge-iterable iterables)</code></div><div class="doc"><div class="markdown"><p>Create an N-way merge iterable using cmp to order the merge of provided iterables.
If a predicate pred is provided the iterable itself will filter out values for which
the pred returns false.  In this mode it is possible for the iterator to return null
if the last value is filtered out -- the hasNext method doesn't check if the next value
passes the predicate.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2734">view source</a></div></div><div class="public anchor" id="var-lines"><h3>lines</h3><div class="usage"><code>(lines fname)</code></div><div class="doc"><div class="markdown"><p>Return a closeable iterable that produces an iterator that simply produces lines of the reader.
Iterator does not cache more than 1 line so there is no possibility of holding onto head normal nor
chunked seq-ing.</p>
<p>Example:</p>
<pre><code class="language-clojure">(with-open [ld (hamf/lines fname)]
  (-&gt;&gt; ld
       (hamf/pmap (fn [line] ...))
       (reduce ...)))
</code></pre>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2701">view source</a></div></div><div class="public anchor" id="var-linked-hashmap"><h3>linked-hashmap</h3><div class="usage"><code>(linked-hashmap)</code><code>(linked-hashmap data)</code></div><div class="doc"><div class="markdown"><p>Linked hash map using clojure's equiv pathways.  At this time the node link order reflects
insertion order.  Modification and access do not affect the node link order.</p>
</div></div><div class="src-link"><a href="https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L549">view source</a></div></div><div class="public anchor" id="var-lnth"><h3>lnth<
Download .txt
gitextract_zg1q5mjk/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── .mise.toml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.clj
├── codegen/
│   └── gen_prim_invoke.clj
├── deps.edn
├── dev/
│   ├── resources/
│   │   └── logback.xml
│   └── src/
│       ├── ham_fisted/
│       │   ├── analysis.clj
│       │   ├── benchmark.clj
│       │   └── protocol_perf.clj
│       └── perftest.clj
├── docs/
│   ├── Reductions.html
│   ├── css/
│   │   └── default.css
│   ├── ham-fisted.api.html
│   ├── ham-fisted.bloom-filter.html
│   ├── ham-fisted.defprotocol.html
│   ├── ham-fisted.fjp.html
│   ├── ham-fisted.function.html
│   ├── ham-fisted.hlet.html
│   ├── ham-fisted.iterator.html
│   ├── ham-fisted.lazy-noncaching.html
│   ├── ham-fisted.mut-map.html
│   ├── ham-fisted.primitive-invoke.html
│   ├── ham-fisted.process.html
│   ├── ham-fisted.profile.html
│   ├── ham-fisted.protocols.html
│   ├── ham-fisted.reduce.html
│   ├── ham-fisted.set.html
│   ├── ham-fisted.spliterator.html
│   ├── highlight/
│   │   └── solarized-light.css
│   ├── index.html
│   └── js/
│       └── page_effects.js
├── java/
│   └── ham_fisted/
│       ├── ArrayHelpers.java
│       ├── ArrayImmutList.java
│       ├── ArrayLists.java
│       ├── ArraySection.java
│       ├── BatchReducer.java
│       ├── BatchedList.java
│       ├── BiFunctions.java
│       ├── BlockSplitBloomFilter.java
│       ├── Casts.java
│       ├── ChunkedList.java
│       ├── CljHash.java
│       ├── ConstList.java
│       ├── ConsumerAccumulators.java
│       ├── Consumers.java
│       ├── CtxIter.java
│       ├── DoubleMutList.java
│       ├── FJTask.java
│       ├── FMapEntry.java
│       ├── ForkJoinPatterns.java
│       ├── HashBase.java
│       ├── HashMap.java
│       ├── HashNode.java
│       ├── HashProvider.java
│       ├── HashProviders.java
│       ├── HashSet.java
│       ├── IAMapEntry.java
│       ├── IAPersistentMap.java
│       ├── IAPersistentSet.java
│       ├── IATransientMap.java
│       ├── IATransientSet.java
│       ├── ICollectionDef.java
│       ├── IFnDef.java
│       ├── IMap.java
│       ├── IMutList.java
│       ├── ISeqDef.java
│       ├── ISet.java
│       ├── ITypedReduce.java
│       ├── ImmutList.java
│       ├── ImmutSort.java
│       ├── IndexedConsumer.java
│       ├── IndexedDoubleConsumer.java
│       ├── IndexedLongConsumer.java
│       ├── IntegerOps.java
│       ├── Iter.java
│       ├── LazyChunkedSeq.java
│       ├── LinkedHashMap.java
│       ├── LinkedHashNode.java
│       ├── LongAccum.java
│       ├── LongHashBase.java
│       ├── LongHashMap.java
│       ├── LongHashNode.java
│       ├── LongMutList.java
│       ├── MapFn.java
│       ├── MapForward.java
│       ├── MapSetOps.java
│       ├── MergeIterator.java
│       ├── MethodImplCache.java
│       ├── MutList.java
│       ├── MutTreeList.java
│       ├── MutableMap.java
│       ├── ObjArray.java
│       ├── ParallelOptions.java
│       ├── PartitionByInner.java
│       ├── PersistentHashMap.java
│       ├── PersistentHashSet.java
│       ├── PersistentLongHashMap.java
│       ├── PersistentVector.java
│       ├── ROHashMap.java
│       ├── ROHashSet.java
│       ├── ROLongHashMap.java
│       ├── RandomAccessSpliterator.java
│       ├── RangeList.java
│       ├── Ranges.java
│       ├── Reducible.java
│       ├── Reductions.java
│       ├── ReindexList.java
│       ├── ReverseList.java
│       ├── SetOps.java
│       ├── StringCollection.java
│       ├── Sum.java
│       ├── Transformables.java
│       ├── TransientHashMap.java
│       ├── TransientHashSet.java
│       ├── TransientList.java
│       ├── TransientLongHashMap.java
│       ├── TreeList.java
│       ├── TreeListBase.java
│       ├── TypedList.java
│       ├── TypedNth.java
│       ├── UnsharedHashMap.java
│       ├── UnsharedHashSet.java
│       ├── UnsharedLongHashMap.java
│       └── UpdateValues.java
├── resources/
│   └── clj-kondo.exports/
│       └── cnuernber/
│           └── ham-fisted/
│               ├── config.edn
│               └── hooks/
│                   └── ham_fisted.clj_kondo
├── results/
│   ├── .keepme
│   ├── concatv.edn
│   ├── d00905c-chrisn-lt3-jdk-1.8.0_312.edn
│   ├── d00905c-chrisn-lt3-jdk-17.0.1.edn
│   ├── general-hashmap.edn
│   ├── persistent-vector.edn
│   ├── random-update.edn
│   ├── sort-by.edn
│   ├── typed-parallel-reductions.edn
│   ├── typed-reductions-intel.edn
│   ├── typed-reductions.edn
│   ├── union-disj.edn
│   ├── union-overlapping.edn
│   ├── union-reduce-transient.edn
│   ├── union-reduce.edn
│   ├── update-values.edn
│   └── vec-equals.edn
├── scripts/
│   ├── benchmark
│   ├── compile
│   ├── deploy
│   ├── enable-jdk17
│   ├── install
│   ├── koacha-test
│   ├── lint
│   ├── reformat
│   └── run-tests
├── src/
│   └── ham_fisted/
│       ├── alists.clj
│       ├── api.clj
│       ├── bloom_filter.clj
│       ├── caffeine.clj
│       ├── datatypes.clj
│       ├── defprotocol.clj
│       ├── fjp.clj
│       ├── function.clj
│       ├── hlet.clj
│       ├── impl.clj
│       ├── iterator.clj
│       ├── language.clj
│       ├── lazy_caching.clj
│       ├── lazy_noncaching.clj
│       ├── mut_map.clj
│       ├── primitive_invoke.clj
│       ├── print.clj
│       ├── process.clj
│       ├── profile.clj
│       ├── protocols.clj
│       ├── reduce.clj
│       ├── set.clj
│       ├── spliterator.clj
│       └── thread_local.clj
├── test/
│   └── ham_fisted/
│       ├── api_test.clj
│       ├── bloom_filter_test.clj
│       ├── cast_test.clj
│       ├── defprotocol_test/
│       │   ├── examples.clj
│       │   ├── hash_collisions_test.clj
│       │   ├── more_examples.clj
│       │   └── other_test.clj
│       ├── defprotocol_test.clj
│       ├── fjp_test.clj
│       ├── hash_map_test.clj
│       ├── hlet_test.clj
│       ├── parallel_test.clj
│       ├── persistent_vector_test.clj
│       ├── test_setup.clj
│       └── vec_like_test.clj
├── tests.edn
└── topics/
    └── Reductions.md
Download .txt
Showing preview only (226K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2676 symbols across 94 files)

FILE: docs/js/page_effects.js
  function visibleInParent (line 1) | function visibleInParent(element) {
  function hasFragment (line 6) | function hasFragment(link, fragment) {
  function findLinkByFragment (line 10) | function findLinkByFragment(elements, fragment) {
  function scrollToCurrentVarLink (line 14) | function scrollToCurrentVarLink(elements) {
  function setCurrentVarLink (line 33) | function setCurrentVarLink() {
  function scrollPositionId (line 47) | function scrollPositionId(element) {
  function storeScrollPosition (line 52) | function storeScrollPosition(element) {
  function recallScrollPosition (line 58) | function recallScrollPosition(element) {
  function persistScrollPosition (line 64) | function persistScrollPosition(element) {
  function sidebarContentWidth (line 69) | function sidebarContentWidth(element) {
  function calculateSize (line 74) | function calculateSize(width, snap, margin, minimum) {
  function resizeSidebars (line 83) | function resizeSidebars() {

FILE: java/ham_fisted/ArrayHelpers.java
  class ArrayHelpers (line 5) | public class ArrayHelpers
    method checkedAget (line 7) | public static Object checkedAget(Object[] data, int nelems, int idx) {
    method aset (line 11) | public static void aset(boolean[] data, int idx, boolean val) {
    method aset (line 14) | public static void aset(byte[] data, int idx, byte val) {
    method aset (line 17) | public static void aset(short[] data, int idx, short val) {
    method aset (line 20) | public static void aset(char[] data, int idx, char val) {
    method aset (line 23) | public static void aset(int[] data, int idx, int val) {
    method aset (line 26) | public static void aset(long[] data, int idx, long val) {
    method aset (line 29) | public static void aset(float[] data, int idx, float val) {
    method aset (line 32) | public static void aset(double[] data, int idx, double val) {
    method aset (line 35) | public static void aset(Object[] data, int idx, Object val) {
    method accumPlus (line 39) | public static void accumPlus(byte[] data, int idx, byte val) {
    method accumPlus (line 42) | public static void accumPlus(short[] data, int idx, short val) {
    method accumPlus (line 45) | public static void accumPlus(char[] data, int idx, char val) {
    method accumPlus (line 48) | public static void accumPlus(int[] data, int idx, int val) {
    method accumPlus (line 51) | public static void accumPlus(long[] data, int idx, long val) {
    method accumPlus (line 54) | public static void accumPlus(float[] data, int idx, float val) {
    method accumPlus (line 57) | public static void accumPlus(double[] data, int idx, double val) {
    method accumMul (line 61) | public static void accumMul(byte[] data, int idx, byte val) {
    method accumMul (line 64) | public static void accumMul(short[] data, int idx, short val) {
    method accumMul (line 67) | public static void accumMul(char[] data, int idx, char val) {
    method accumMul (line 70) | public static void accumMul(int[] data, int idx, int val) {
    method accumMul (line 73) | public static void accumMul(long[] data, int idx, long val) {
    method accumMul (line 76) | public static void accumMul(float[] data, int idx, float val) {
    method accumMul (line 79) | public static void accumMul(double[] data, int idx, double val) {
    method manualCopy (line 86) | public static void manualCopy(Object[] src, int soff, Object[] dst, in...
    method manualCopy (line 91) | public static void manualCopy(byte[] src, int soff, byte[] dst, int do...
    method manualCopy (line 96) | public static void manualCopy(short[] src, int soff, short[] dst, int ...
    method manualCopy (line 101) | public static void manualCopy(char[] src, int soff, char[] dst, int do...
    method manualCopy (line 106) | public static void manualCopy(int[] src, int soff, int[] dst, int doff...
    method manualCopy (line 111) | public static void manualCopy(long[] src, int soff, long[] dst, int do...
    method manualCopy (line 116) | public static void manualCopy(float[] src, int soff, float[] dst, int ...
    method manualCopy (line 121) | public static void manualCopy(double[] src, int soff, double[] dst, in...

FILE: java/ham_fisted/ArrayImmutList.java
  class ArrayImmutList (line 41) | public class ArrayImmutList
    method ArrayImmutList (line 55) | public ArrayImmutList(Object[] d, int sidx, int eidx, IPersistentMap m...
    method create (line 61) | public static ArrayImmutList create(boolean owning, Object[] d,
    method create (line 66) | public static IPersistentVector create(boolean owning, IPersistentMap ...
    method indexCheck (line 69) | final int indexCheck(int idx) {
    method wrapIndexCheck (line 72) | final int wrapIndexCheck(int idx) {
    method getChunkedList (line 75) | public ChunkedListSection getChunkedList() {
    method hashCode (line 78) | public final int hashCode() {
    method hasheq (line 91) | public final int hasheq() { return hashCode(); }
    method equiv (line 92) | public final boolean equiv(HashProvider hp, Object other) {
    method equiv (line 111) | public final boolean equiv(Object other) {
    method equals (line 114) | public final boolean equals(Object other) {
    method toString (line 117) | public final String toString() {
    method meta (line 120) | public final IPersistentMap meta() { return m; }
    method withMeta (line 121) | public final ArrayImmutList withMeta(IPersistentMap m) {
    method clear (line 124) | public void clear() { throw new RuntimeException("Unimplemented"); }
    method remove (line 125) | public boolean remove(Object c) { throw new RuntimeException("Unimplem...
    method remove (line 126) | public Character remove(int idx) { throw new RuntimeException("Unimple...
    method add (line 127) | public boolean add(Object c) { throw new RuntimeException("Unimplement...
    method add (line 128) | public void add(int idx, Object c) { throw new RuntimeException("Unimp...
    method addAll (line 129) | public boolean addAll(int idx, Collection c)
    method set (line 131) | public Character set(int idx, Object c) { throw new RuntimeException("...
    method retainAll (line 132) | public boolean retainAll(Collection c) { throw new RuntimeException("U...
    method removeAll (line 133) | public boolean removeAll(Collection c) { throw new RuntimeException("U...
    method addAll (line 134) | public boolean addAll(Collection c) { throw new RuntimeException("Unim...
    method get (line 135) | public Object get(int idx) {
    method indexOf (line 138) | public final int indexOf(Object obj) {
    method lastIndexOf (line 147) | public final int lastIndexOf(Object obj) {
    method size (line 159) | public final int size() { return nElems; }
    method length (line 160) | public final int length() { return nElems; }
    method count (line 161) | public final int count() { return nElems; }
    method contains (line 162) | public final boolean contains(Object obj) {
    method isEmpty (line 165) | public boolean isEmpty() { return nElems == 0; }
    method fillArray (line 166) | public Object[] fillArray(Object[] retval) {
    method toArray (line 170) | public Object[] toArray() {
    method toArray (line 173) | public Object[] toArray(Object[] marker) {
    method subList (line 176) | public ArrayImmutList subList(int sidx, int endidx) {
    class Iter (line 180) | static class Iter implements Iterator {
      method Iter (line 184) | public Iter(Object[] d, int startidx, int nElems) {
      method hasNext (line 189) | public final boolean hasNext() { return idx < endidx; }
      method next (line 190) | public final Object next() {
    method iterator (line 198) | public final Iterator iterator() { return new Iter(data, startidx, nEl...
    class RIter (line 199) | static class RIter implements Iterator {
      method RIter (line 205) | public RIter(Object[] d, int startidx, int nElems) {
      method hasNext (line 211) | public final boolean hasNext() { return idx <= nne; }
      method next (line 212) | public final Object next() {
    method riterator (line 220) | public final Iterator riterator() { return new RIter(data, startidx, n...
    method nth (line 221) | public final Object nth(int idx, Object notFound) {
    method nth (line 228) | public final Object nth(int idx) {
    method invoke (line 231) | public final Object invoke(Object idx) {
    method invoke (line 236) | public final Object invoke(Object idx, Object notFound) {
    method valAt (line 241) | public final Object valAt(Object idx) {
    method valAt (line 244) | public final Object valAt(Object idx, Object notFound) {
    method entryAt (line 247) | public final IMapEntry entryAt(Object key) {
    method containsKey (line 255) | public final boolean containsKey(Object key) {
    method empty (line 262) | public final ArrayImmutList empty() { return EMPTY.withMeta(m); }
    method reduce (line 263) | public final Object reduce(IFn f, Object init) {
    method kvreduce (line 273) | public final Object kvreduce(IFn fn, Object init) {
    method seq (line 282) | public final ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(itera...
    method rseq (line 283) | public final ISeq rseq() { return LazyChunkedSeq.chunkIteratorSeq(rite...
    method asArray (line 284) | Object[] asArray() {
    method cons (line 289) | public final IPersistentVector cons(Object obj) {
    method assocN (line 298) | public final IPersistentVector assocN(int idx, Object obj) {
    method assoc (line 308) | public final IPersistentVector assoc(Object idx, Object obj) {
    method pop (line 313) | public final ArrayImmutList pop() {
    method peek (line 320) | public final Object peek() {
    method asTransient (line 325) | public final MutTreeList asTransient() {
    method updateValue (line 328) | @SuppressWarnings("unchecked")
    method updateValues (line 339) | @SuppressWarnings("unchecked")
    method getArraySection (line 349) | public ArraySection getArraySection() {
    method move (line 352) | public void move(int sidx, int eidx, int count) { throw new RuntimeExc...
    method fill (line 353) | public void fill(int sidx, int eidx, Object v) {
    method copyOfRange (line 356) | public Object copyOfRange(int sidx, int eidx) {
    method copyOf (line 359) | public Object copyOf(int len) {

FILE: java/ham_fisted/ArrayLists.java
  class ArrayLists (line 53) | public class ArrayLists {
    method checkIndex (line 54) | public static int checkIndex(final int idx, final int dlen) {
    method wrapCheckIndex (line 58) | public static int wrapCheckIndex(int idx, final int dlen) {
    method checkIndexRange (line 63) | public static void checkIndexRange(int dlen, int ssidx, int seidx) {
    method checkIndexRange (line 66) | public static void checkIndexRange(long dlen, long ssidx, long seidx) {
    method asDoubleConsumer (line 69) | public static DoubleConsumer asDoubleConsumer(Object c) {
    method asLongConsumer (line 74) | public static LongConsumer asLongConsumer(Object c) {
    type ArrayOwner (line 79) | public interface ArrayOwner {
      method getArraySection (line 80) | ArraySection getArraySection();
      method fill (line 81) | void fill(int sidx, int eidx, Object v);
      method copyOfRange (line 82) | Object copyOfRange(int sidx, int eidx);
      method copyOf (line 83) | Object copyOf(int len);
      method move (line 85) | void move(int sourceIdx, int dstIdx, int count);
    type ArrayPersistentVector (line 87) | public interface ArrayPersistentVector extends IMutList<Object>, IPers...
      method unsafeImmut (line 88) | IPersistentVector unsafeImmut();
      method equiv (line 89) | default boolean equiv(Object other) {
      method cons (line 92) | default IPersistentVector cons(Object o) { return immut().cons(o); }
      method assocN (line 93) | default IPersistentVector assocN(int i, Object o) {
      method length (line 96) | default int length() { return size(); }
      method assoc (line 97) | default Associative assoc(Object idx, Object o) {
      method pop (line 100) | default IPersistentStack pop() {
      method peek (line 108) | default Object peek() {
      method empty (line 114) | default ImmutList empty() {
    method fillRangeArrayCopy (line 118) | @SuppressWarnings("unchecked")
    method immutShuffleDefault (line 140) | static List immutShuffleDefault(IMutList m, Random r) {
    method immutSortDefault (line 145) | @SuppressWarnings("unchecked")
    type IArrayList (line 151) | public interface IArrayList extends IMutList<Object>, ArrayOwner, Type...
      method add (line 153) | default void add(int idx, int count, Object obj) {
      method containedType (line 164) | default Class containedType() { return getArraySection().array.getCl...
      method unsafeImmut (line 165) | default IPersistentVector unsafeImmut() { return ImmutList.create(tr...
      method immutShuffle (line 166) | default List immutShuffle(Random r) { return immutShuffleDefault(thi...
      method immutSort (line 167) | default List immutSort(Comparator c) { return immutSortDefault(this,...
      method fillRange (line 168) | default void fillRange(long startidx, long endidx, Object v) {
      method fillRangeReducible (line 172) | default void fillRangeReducible(long startidx, Object v) {
      method setSize (line 178) | default void setSize(int size ) { throw new RuntimeException("unimpl...
      method ensureCapacity (line 179) | default Object ensureCapacity(int newlen) {
    type ILongArrayList (line 183) | public interface ILongArrayList extends LongMutList, ArrayOwner, Typed...
      method add (line 186) | default void add(int idx, int count, Object obj) {
      method containedType (line 197) | default Class containedType() { return getArraySection().array.getCl...
      method unsafeImmut (line 198) | default IPersistentVector unsafeImmut() { return ImmutList.create(tr...
      method immutShuffle (line 199) | default List immutShuffle(Random r) { return immutShuffleDefault(thi...
      method immutSort (line 200) | default List immutSort(Comparator c) { return immutSortDefault(this,...
      method fillRange (line 201) | default void fillRange(long startidx, long endidx, Object v) {
      method fillRangeReducible (line 205) | default void fillRangeReducible(long startidx, Object v) {
      method reduce (line 210) | default Object reduce(IFn rfn, Object init) {
      method toNativeArray (line 213) | default Object toNativeArray() { return copyOf(size()); }
      method setSize (line 214) | default void setSize(int size ) { throw new RuntimeException("unimpl...
      method ensureCapacity (line 215) | default Object ensureCapacity(int newlen) {
    type IDoubleArrayList (line 219) | public interface IDoubleArrayList extends DoubleMutList, ArrayOwner, T...
      method add (line 222) | default void add(int idx, int count, Object obj) {
      method containedType (line 233) | default Class containedType() { return getArraySection().array.getCl...
      method unsafeImmut (line 234) | default IPersistentVector unsafeImmut() { return ImmutList.create(tr...
      method immutShuffle (line 235) | default List immutShuffle(Random r) { return immutShuffleDefault(thi...
      method immutSort (line 236) | default List immutSort(Comparator c) { return immutSortDefault(this,...
      method fillRange (line 237) | default void fillRange(long startidx, long endidx, Object v) {
      method fillRangeReducible (line 241) | default void fillRangeReducible(long startidx, Object v) {
      method toNativeArray (line 246) | default Object toNativeArray() { return copyOf(size()); }
      method setSize (line 247) | default void setSize(int size ) { throw new RuntimeException("unimpl...
      method ensureCapacity (line 248) | default Object ensureCapacity(int newlen) {
    method fixSubArrayBinarySearch (line 253) | static int fixSubArrayBinarySearch(final int sidx, final int len, fina...
    method objectArray (line 257) | public static Object[] objectArray(int len) { return new Object[len]; }
    class ObjectArraySubList (line 259) | public static class ObjectArraySubList implements IArrayList {
      method ObjectArraySubList (line 265) | public ObjectArraySubList(Object[] d, int _sidx, int _eidx, IPersist...
      method isCompatible (line 272) | public boolean isCompatible(Object other) {
      method toString (line 275) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 276) | public boolean equals(Object other) {
      method hashCode (line 279) | public int hashCode() { return hasheq(); }
      method getArraySection (line 280) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 281) | public Class containedType() { return data.getClass().getComponentTy...
      method size (line 282) | public int size() { return nElems; }
      method get (line 283) | public Object get(int idx) { return data[checkIndex(idx, nElems) + s...
      method nth (line 284) | public Object nth(int idx) {
      method set (line 287) | public Object set(int idx, Object obj) {
      method subList (line 293) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 297) | public IPersistentMap meta() { return meta; }
      method withMeta (line 298) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 301) | public Object[] toArray() {
      method sort (line 304) | public void sort(Comparator<? super Object> c) {
      method shuffle (line 310) | public void shuffle(Random r) {
      method binarySearch (line 313) | @SuppressWarnings("unchecked")
      method forEach (line 320) | @SuppressWarnings("unchecked")
      method fillRangeReducible (line 327) | public void fillRangeReducible(long startidx, Object v) {
      method reduce (line 343) | public Object reduce(IFn rfn, Object acc) {
      method immut (line 353) | public IPersistentVector immut() {
      method move (line 356) | public void move(int sidx, int eidx, int count) {
      method fill (line 360) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 364) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 367) | public Object copyOf(int len) {
    method newArrayLen (line 372) | public static int newArrayLen(int len) {
    method newArrayLen (line 376) | public static long newArrayLen(long len) {
    class ObjectArrayList (line 380) | public static class ObjectArrayList implements IArrayList, ITransientC...
      method ObjectArrayList (line 384) | public ObjectArrayList(Object[] d, int ne, IPersistentMap meta) {
      method ObjectArrayList (line 388) | public ObjectArrayList(int capacity) {
      method ObjectArrayList (line 391) | public ObjectArrayList() {
      method toString (line 394) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 395) | public boolean equals(Object other) {
      method hashCode (line 398) | public int hashCode() { return hasheq(); }
      method cloneList (line 399) | public IMutList cloneList() { return new ObjectArrayList((Object[])c...
      method getArraySection (line 401) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 402) | public Class containedType() { return data.getClass().getComponentTy...
      method clear (line 403) | public void clear() { nElems = 0; }
      method size (line 404) | public int size() { return nElems; }
      method setSize (line 405) | public void setSize(int sz) { nElems = sz; }
      method get (line 406) | public Object get(int idx) { return data[checkIndex(idx, nElems)]; }
      method set (line 407) | public Object set(int idx, Object obj) {
      method capacity (line 413) | public int capacity() { return data.length; }
      method ensureCapacity (line 414) | public Object[] ensureCapacity(int len) {
      method add (line 421) | public boolean add(Object obj) {
      method add (line 428) | public void add(int idx, Object obj) {
      method addAllReducible (line 440) | public boolean addAllReducible(Object c) {
      method subList (line 455) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 459) | public IPersistentMap meta() { return meta; }
      method withMeta (line 460) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 464) | public Object[] toArray() {
      method removeRange (line 467) | public void removeRange(int startidx, int endidx) {
      method reduce (line 473) | public Object reduce(IFn fn) { return ((IReduce)subList(0, nElems))....
      method reduce (line 474) | public Object reduce(IFn fn, Object init) { return ((IReduceInit)sub...
      method sort (line 475) | public void sort(Comparator<? super Object> c) {
      method shuffle (line 478) | public void shuffle(Random r) {
      method forEach (line 481) | @SuppressWarnings("unchecked")
      method fillRangeReducible (line 488) | public void fillRangeReducible(long startidx, Object v) {
      method immut (line 491) | public IPersistentVector immut() {
      method persistent (line 494) | public IPersistentCollection persistent() {
      method conj (line 497) | public final ObjectArrayList conj(Object obj) {
      method move (line 501) | public void move(int sidx, int eidx, int count) {
      method fill (line 505) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 509) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 512) | public Object copyOf(int len) {
      method wrap (line 515) | public static ObjectArrayList wrap(final Object[] data, int nElems, ...
      method wrap (line 520) | public static ObjectArrayList wrap(final Object[] data, IPersistentM...
    method toArray (line 525) | @SuppressWarnings("unchecked")
    method toArray (line 541) | @SuppressWarnings("unchecked")
    method toList (line 557) | public static IMutList<Object> toList(final Object[] data, final int s...
    method toList (line 561) | public static IMutList<Object> toList(final Object[] data) { return to...
    class ByteArraySubList (line 564) | public static class ByteArraySubList implements ILongArrayList {
      method ByteArraySubList (line 569) | public ByteArraySubList(byte[] d, int s, int len, IPersistentMap _me...
      method toString (line 575) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 576) | public boolean equals(Object other) {
      method hashCode (line 579) | public int hashCode() { return hasheq(); }
      method getArraySection (line 580) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 581) | public Class containedType() { return data.getClass().getComponentTy...
      method size (line 582) | public int size() { return dlen; }
      method get (line 583) | public Byte get(int idx) { return data[checkIndex(idx, dlen) + sidx]; }
      method getLong (line 584) | public long getLong(int idx) { return data[checkIndex(idx, dlen) + s...
      method setLong (line 585) | public void setLong(int idx, long oobj) {
      method cloneList (line 588) | public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfR...
      method indexComparator (line 589) | public IntComparator indexComparator() {
      method subList (line 596) | public LongMutList subList(int ssidx, int seidx) {
      method meta (line 600) | public IPersistentMap meta() { return meta; }
      method withMeta (line 601) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 604) | public Object[] toArray() {
      method sort (line 611) | @SuppressWarnings("unchecked")
      method shuffle (line 619) | public void shuffle(Random r) {
      method asByteComparator (line 622) | public static ByteComparator asByteComparator(Comparator c) {
      method binarySearch (line 634) | @SuppressWarnings("unchecked")
      method longReduction (line 644) | public Object longReduction(IFn.OLO rfn, Object init) {
      method fillRangeReducible (line 652) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 669) | public void move(int sidx, int eidx, int count) {
      method fill (line 673) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 677) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 680) | public Object copyOf(int len) {
    method toList (line 685) | public static IMutList<Object> toList(final byte[] data, final int sid...
    method toList (line 689) | public static IMutList<Object> toList(final byte[] data) { return toLi...
    class ShortArraySubList (line 692) | public static class ShortArraySubList implements ILongArrayList {
      method ShortArraySubList (line 698) | public ShortArraySubList(short[] d, int s, int len, IPersistentMap _...
      method toString (line 704) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 705) | public boolean equals(Object other) {
      method hashCode (line 708) | public int hashCode() { return hasheq(); }
      method cloneList (line 709) | public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfR...
      method getArraySection (line 710) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 711) | public Class containedType() { return data.getClass().getComponentTy...
      method size (line 712) | public int size() { return dlen; }
      method getLong (line 713) | public long getLong(int idx) { return data[checkIndex(idx, dlen) + s...
      method setLong (line 714) | public void setLong(int idx, long oobj) {
      method indexComparator (line 717) | public IntComparator indexComparator() {
      method subList (line 724) | public LongMutList subList(int ssidx, int seidx) {
      method meta (line 728) | public IPersistentMap meta() { return meta; }
      method withMeta (line 729) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 732) | public Object[] toArray() {
      method sort (line 739) | @SuppressWarnings("unchecked")
      method shuffle (line 755) | public void shuffle(Random r) {
      method asShortComparator (line 758) | public static ShortComparator asShortComparator(Comparator c) {
      method binarySearch (line 769) | @SuppressWarnings("unchecked")
      method longReduction (line 778) | public Object longReduction(IFn.OLO rfn, Object init) {
      method fillRangeReducible (line 785) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 802) | public void move(int sidx, int eidx, int count) {
      method fill (line 806) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 810) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 814) | public Object copyOf(int len) {
    method toList (line 819) | public static IMutList<Object> toList(final short[] data, final int si...
    method toList (line 823) | public static IMutList<Object> toList(final short[] data) { return toL...
    method intArray (line 825) | public static int[] intArray(int len) { return new int[len]; }
    class IntArraySubList (line 826) | public static class IntArraySubList implements ILongArrayList {
      method IntArraySubList (line 832) | public IntArraySubList(int[] d, int _sidx, int _eidx, IPersistentMap...
      method toString (line 839) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 840) | public boolean equals(Object other) {
      method hashCode (line 843) | public int hashCode() { return hasheq(); }
      method cloneList (line 844) | public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfR...
      method getArraySection (line 845) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 846) | public Class containedType() { return data.getClass().getComponentTy...
      method size (line 847) | public int size() { return nElems; }
      method getLong (line 848) | public long getLong(int idx) { return data[checkIndex(idx, nElems) +...
      method setLong (line 849) | static void setLong(final int[] d, final int sidx, final int nElems,
      method setLong (line 855) | public void setLong(int idx, long obj) {
      method subList (line 858) | public LongMutList subList(int ssidx, int seidx) {
      method meta (line 862) | public IPersistentMap meta() { return meta; }
      method withMeta (line 863) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 866) | public Object[] toArray() {
      method toIntArray (line 875) | public int[] toIntArray() {
      method indexComparator (line 878) | @SuppressWarnings("unchecked")
      method indexComparator (line 919) | public IntComparator indexComparator() {
      method indexComparator (line 922) | public IntComparator indexComparator(Comparator c) {
      method toIntComparator (line 925) | @SuppressWarnings("unchecked")
      method sort (line 936) | public void sort(Comparator<? super Object> c) {
      method shuffle (line 943) | public void shuffle(Random r) {
      method asIntComparator (line 946) | public static IntComparator asIntComparator(Comparator c) {
      method binarySearch (line 958) | @SuppressWarnings("unchecked")
      method sortIndirect (line 967) | public int[] sortIndirect(Comparator c) {
      method reduce (line 978) | public Object reduce(IFn rfn, Object init) {
      method longReduction (line 981) | public Object longReduction(IFn.OLO rfn, Object init) {
      method fillRangeReducible (line 988) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 1004) | public void move(int sidx, int eidx, int count) {
      method fill (line 1008) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 1012) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 1016) | public Object copyOf(int len) {
    class IntArrayList (line 1021) | public static class IntArrayList implements ILongArrayList {
      method IntArrayList (line 1025) | public IntArrayList(int[] d, int ne, IPersistentMap meta) {
      method IntArrayList (line 1029) | public IntArrayList(int capacity) {
      method IntArrayList (line 1032) | public IntArrayList() {
      method toString (line 1035) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 1036) | public boolean equals(Object other) {
      method hashCode (line 1039) | public int hashCode() { return hasheq(); }
      method cloneList (line 1040) | public IMutList cloneList() { return new IntArrayList((int[])copyOf(...
      method getArraySection (line 1042) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 1043) | public Class containedType() { return data.getClass().getComponentTy...
      method size (line 1044) | public int size() { return nElems; }
      method setSize (line 1045) | public void setSize(int sz) { nElems = sz; }
      method getLong (line 1046) | public long getLong(int idx) { return data[checkIndex(idx, nElems)]; }
      method setLong (line 1047) | public void setLong(int idx, long obj) {
      method capacity (line 1050) | public int capacity() { return data.length; }
      method clear (line 1051) | public void clear() { nElems = 0; }
      method ensureCapacity (line 1052) | public int[] ensureCapacity(int len) {
      method addLong (line 1059) | public void addLong(long obj) {
      method add (line 1066) | public void add(int idx, Object obj) {
      method addAllReducible (line 1077) | public boolean addAllReducible(Object c) {
      method addAll (line 1092) | public boolean addAll(int sidx, Collection <? extends Object> c) {
      method subList (line 1104) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 1108) | public IPersistentMap meta() { return meta; }
      method withMeta (line 1109) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 1113) | public Object[] toArray() {
      method toIntArray (line 1116) | public int[] toIntArray() {
      method fillRange (line 1119) | public void fillRange(long startidx, long endidx, Object v) {
      method fillRangeReducible (line 1122) | public void fillRangeReducible(long startidx, Object v) {
      method addRange (line 1125) | public void addRange(final int startidx, final int endidx, final Obj...
      method removeRange (line 1134) | public void removeRange(int startidx, int endidx) {
      method reduce (line 1139) | public Object reduce(IFn fn) { return ((IReduce)subList(0, nElems))....
      method reduce (line 1140) | public Object reduce(IFn fn, Object init) { return ((IReduceInit)sub...
      method longReduction (line 1141) | public Object longReduction(IFn.OLO op, long init) {
      method sort (line 1144) | public void sort(Comparator<? super Object> c) {
      method shuffle (line 1147) | public void shuffle(Random r) {
      method sortIndirect (line 1150) | public int[] sortIndirect(Comparator c) {
      method binarySearch (line 1153) | @SuppressWarnings("unchecked")
      method indexComparator (line 1157) | public IntComparator indexComparator() {
      method indexComparator (line 1160) | public IntComparator indexComparator(Comparator c) {
      method longReduction (line 1163) | public Object longReduction(IFn.OLO rfn, Object init) {
      method move (line 1170) | public void move(int sidx, int eidx, int count) {
      method fill (line 1174) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 1178) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 1182) | public Object copyOf(int len) {
      method wrap (line 1185) | public static IntArrayList wrap(final int[] data, int nElems, IPersi...
      method wrap (line 1190) | public static IntArrayList wrap(final int[] data, IPersistentMap m) {
    method intIndexComparator (line 1195) | @SuppressWarnings("unchecked")
    method toList (line 1220) | public static IMutList<Object> toList(final int[] data, final int sidx...
    method toList (line 1224) | public static IMutList<Object> toList(final int[] data) { return toLis...
    method longArray (line 1226) | public static long[] longArray(int len) { return new long[len]; }
    class LongArraySubList (line 1227) | public static class LongArraySubList implements ILongArrayList {
      method LongArraySubList (line 1233) | public LongArraySubList(long[] d, int _sidx, int _eidx, IPersistentM...
      method toString (line 1240) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 1241) | public boolean equals(Object other) {
      method hashCode (line 1244) | public int hashCode() { return hasheq(); }
      method getArraySection (line 1245) | public ArraySection getArraySection() { return new ArraySection(data...
      method cloneList (line 1246) | public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfR...
      method containedType (line 1247) | public Class containedType() { return data.getClass().getComponentTy...
      method size (line 1248) | public int size() { return nElems; }
      method getLong (line 1249) | public long getLong(int idx) { return data[checkIndex(idx, nElems) +...
      method get (line 1250) | public Object get(int idx) { return data[checkIndex(idx, nElems) + s...
      method nth (line 1251) | public Object nth(int idx) {
      method setLong (line 1254) | static void setLong(final long[] d, final int sidx, final int nElems,
      method setLong (line 1259) | public void setLong(int idx, long obj) {
      method subList (line 1262) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 1266) | public IPersistentMap meta() { return meta; }
      method withMeta (line 1267) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 1270) | public Object[] toArray() {
      method toLongArray (line 1279) | public long[] toLongArray() {
      method indexComparator (line 1282) | @SuppressWarnings("unchecked")
      method indexComparator (line 1323) | public IntComparator indexComparator() {
      method indexComparator (line 1326) | public IntComparator indexComparator(Comparator c) {
      method toLongComparator (line 1330) | @SuppressWarnings("unchecked")
      method sort (line 1341) | public void sort(Comparator<? super Object> c) {
      method sortIndirect (line 1348) | public int[] sortIndirect(Comparator c) {
      method shuffle (line 1359) | public void shuffle(Random r) {
      method asLongComparator (line 1362) | public static LongComparator asLongComparator(Comparator c) {
      method binarySearch (line 1367) | @SuppressWarnings("unchecked")
      method longReduction (line 1376) | public Object longReduction(IFn.OLO rfn, Object init) {
      method longForEach (line 1383) | public void longForEach(LongConsumer c) {
      method fillRangeReducible (line 1389) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 1405) | public void move(int sidx, int eidx, int count) {
      method fill (line 1409) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 1413) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 1416) | public Object copyOf(int len) {
    class LongArrayList (line 1421) | public static class LongArrayList implements ILongArrayList {
      method LongArrayList (line 1425) | public LongArrayList(long[] d, int ne, IPersistentMap meta) {
      method LongArrayList (line 1429) | public LongArrayList(int capacity) {
      method LongArrayList (line 1432) | public LongArrayList() {
      method toString (line 1435) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 1436) | public boolean equals(Object other) {
      method hashCode (line 1439) | public int hashCode() { return hasheq(); }
      method cloneList (line 1440) | public IMutList cloneList() { return new LongArrayList((long[])copyO...
      method getArraySection (line 1442) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 1443) | public Class containedType() { return data.getClass().getComponentTy...
      method clear (line 1444) | public void clear() { nElems = 0; }
      method size (line 1445) | public int size() { return nElems; }
      method setSize (line 1446) | public void setSize(int sz) { nElems = sz; }
      method getLong (line 1447) | public long getLong(int idx) { return data[checkIndex(idx, nElems)]; }
      method setLong (line 1448) | public void setLong(int idx, long obj) {
      method capacity (line 1451) | public int capacity() { return data.length; }
      method ensureCapacity (line 1452) | public long[] ensureCapacity(int len) {
      method addLong (line 1459) | public void addLong(long val) {
      method add (line 1465) | public boolean add(Object obj) { addLong(Casts.longCast(obj)); retur...
      method add (line 1466) | public void add(int idx, Object obj) {
      method addAllReducible (line 1477) | public boolean addAllReducible(Object c) {
      method addAll (line 1492) | public boolean addAll(int sidx, Collection <? extends Object> c) {
      method remove (line 1504) | public Object remove(int idx) {
      method subList (line 1517) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 1521) | public IPersistentMap meta() { return meta; }
      method withMeta (line 1522) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 1526) | public Object[] toArray() {
      method toLongArray (line 1529) | public long[] toLongArray() {
      method fillRange (line 1532) | public void fillRange(long startidx, long endidx, Object v) {
      method fillRangeReducible (line 1535) | public void fillRangeReducible(long startidx, List v) {
      method addRange (line 1538) | public void addRange(final int startidx, final int endidx, final Obj...
      method removeRange (line 1546) | public void removeRange(int startidx, int endidx) {
      method reduce (line 1551) | public Object reduce(IFn fn) { return ((IReduce)subList(0, nElems))....
      method reduce (line 1552) | public Object reduce(IFn fn, Object init) { return ((IReduceInit)sub...
      method longReduction (line 1553) | public Object longReduction(IFn.OLO op, Object init) {
      method indexComparator (line 1556) | public IntComparator indexComparator() {
      method indexComparator (line 1559) | public IntComparator indexComparator(Comparator c) {
      method sort (line 1562) | public void sort(Comparator<? super Object> c) {
      method shuffle (line 1565) | public void shuffle(Random r) {
      method binarySearch (line 1568) | @SuppressWarnings("unchecked")
      method sortIndirect (line 1572) | public int[] sortIndirect(Comparator c) {
      method fillRangeReducible (line 1575) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 1578) | public void move(int sidx, int eidx, int count) {
      method fill (line 1582) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 1586) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 1590) | public Object copyOf(int len) {
      method wrap (line 1593) | public static LongArrayList wrap(final long[] data, int nElems, IPer...
      method wrap (line 1598) | public static LongArrayList wrap(final long[] data, IPersistentMap m) {
    method toList (line 1604) | public static IMutList<Object> toList(final long[] data, final int sid...
    method toList (line 1607) | public static IMutList<Object> toList(final long[] data) { return toLi...
    method floatArray (line 1609) | public static float[] floatArray(int len) { return new float[len]; }
    class FloatArraySubList (line 1610) | public static class FloatArraySubList implements IDoubleArrayList {
      method FloatArraySubList (line 1616) | public FloatArraySubList(float[] d, int s, int len, IPersistentMap _...
      method toString (line 1622) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 1623) | public boolean equals(Object other) {
      method hashCode (line 1626) | public int hashCode() { return hasheq(); }
      method cloneList (line 1627) | public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfR...
      method getArraySection (line 1628) | public ArraySection getArraySection() { return new ArraySection(data...
      method size (line 1629) | public int size() { return dlen; }
      method get (line 1630) | public Float get(int idx) { return data[checkIndex(idx, dlen) + sidx...
      method getDouble (line 1631) | public double getDouble(int idx) { return data[checkIndex(idx, dlen)...
      method setDouble (line 1632) | public void setDouble(int idx, double v) {
      method subList (line 1637) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 1641) | public IPersistentMap meta() { return meta; }
      method withMeta (line 1642) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 1645) | public Object[] toArray() {
      method toFloatArray (line 1652) | public float[] toFloatArray() {
      method indexComparator (line 1655) | public IntComparator indexComparator() {
      method indexComparator (line 1670) | public IntComparator indexComparator(Comparator c) {
      method asFloatComparator (line 1691) | public static FloatComparator asFloatComparator(Comparator c) {
      method sort (line 1702) | @SuppressWarnings("unchecked")
      method shuffle (line 1714) | public void shuffle(Random r) {
      method binarySearch (line 1717) | @SuppressWarnings("unchecked")
      method doubleReduction (line 1726) | public Object doubleReduction(IFn.ODO rfn, Object init) {
      method fillRangeReducible (line 1733) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 1750) | public void move(int sidx, int eidx, int count) {
      method fill (line 1754) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 1758) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 1762) | public Object copyOf(int len) {
    method toList (line 1767) | public static IMutList<Object> toList(final float[] data, final int si...
    method toList (line 1771) | public static IMutList<Object> toList(final float[] data) { return toL...
    method doubleArray (line 1773) | public static double[] doubleArray(int len) {
    class DoubleArraySubList (line 1777) | public static class DoubleArraySubList implements IDoubleArrayList {
      method DoubleArraySubList (line 1783) | public DoubleArraySubList(double[] d, int _sidx, int _eidx, IPersist...
      method toString (line 1790) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 1791) | public boolean equals(Object other) {
      method hashCode (line 1794) | public int hashCode() { return hasheq(); }
      method cloneList (line 1795) | public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfR...
      method getArraySection (line 1796) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 1797) | public Class containedType() { return data.getClass().getComponentTy...
      method size (line 1798) | public int size() { return nElems; }
      method getDouble (line 1799) | public double getDouble(int idx) { return data[checkIndex(idx, nElem...
      method get (line 1800) | public Object get(int idx) { return data[checkIndex(idx, nElems) + s...
      method nth (line 1801) | public Object nth(int idx) {
      method setDouble (line 1806) | static void setDouble(final double[] d, final int sidx, final int nE...
      method setDouble (line 1811) | public void setDouble(int idx, double obj) {
      method subList (line 1814) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 1818) | public IPersistentMap meta() { return meta; }
      method withMeta (line 1819) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 1822) | public Object[] toArray() {
      method toDoubleArray (line 1831) | public double[] toDoubleArray() {
      method indexComparator (line 1834) | @SuppressWarnings("unchecked")
      method indexComparator (line 1876) | public IntComparator indexComparator() {
      method indexComparator (line 1879) | public IntComparator indexComparator(Comparator c) {
      method toDoubleComparator (line 1882) | @SuppressWarnings("unchecked")
      method sort (line 1888) | public void sort(Comparator<? super Object> c) {
      method sortIndirect (line 1900) | public int[] sortIndirect(Comparator c) {
      method shuffle (line 1911) | public void shuffle(Random r) {
      method asDoubleComparator (line 1914) | public static DoubleComparator asDoubleComparator(Comparator c) {
      method binarySearch (line 1919) | @SuppressWarnings("unchecked")
      method doubleReduction (line 1928) | public Object doubleReduction(IFn.ODO rfn, Object init) {
      method fillRangeReducible (line 1935) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 1951) | public void move(int sidx, int eidx, int count) {
      method fill (line 1955) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 1959) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 1963) | public Object copyOf(int len) {
    class DoubleArrayList (line 1968) | public static class DoubleArrayList implements IDoubleArrayList {
      method DoubleArrayList (line 1972) | public DoubleArrayList(double[] d, int ne, IPersistentMap meta) {
      method DoubleArrayList (line 1976) | public DoubleArrayList(int capacity) {
      method DoubleArrayList (line 1979) | public DoubleArrayList() {
      method toString (line 1982) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 1983) | public boolean equals(Object other) {
      method hashCode (line 1986) | public int hashCode() { return hasheq(); }
      method cloneList (line 1987) | public IMutList cloneList() { return new DoubleArrayList((double[])c...
      method getArraySection (line 1989) | public ArraySection getArraySection() { return new ArraySection(data...
      method containedType (line 1990) | public Class containedType() { return data.getClass().getComponentTy...
      method clear (line 1991) | public void clear() { nElems = 0; }
      method size (line 1992) | public int size() { return nElems; }
      method setSize (line 1993) | public void setSize(int sz) { nElems = sz; }
      method getDouble (line 1994) | public double getDouble(int idx) { return data[checkIndex(idx, nElem...
      method setDouble (line 1995) | public void setDouble(int idx, double obj) {
      method capacity (line 1998) | public int capacity() { return data.length; }
      method ensureCapacity (line 1999) | public double[] ensureCapacity(int len) {
      method addDouble (line 2006) | public void addDouble(double obj) {
      method add (line 2012) | public boolean add(Object obj) { addDouble(Casts.doubleCast(obj)); r...
      method add (line 2013) | public void add(int idx, Object obj) {
      method addAllReducible (line 2024) | public boolean addAllReducible(Object c) {
      method addAll (line 2039) | public boolean addAll(int sidx, Collection <? extends Object> c) {
      method remove (line 2060) | public Object remove(int idx) {
      method subList (line 2073) | public IMutList<Object> subList(int ssidx, int seidx) {
      method fillRangeReducible (line 2077) | public void fillRangeReducible(long startidx, List v) {
      method meta (line 2080) | public IPersistentMap meta() { return meta; }
      method withMeta (line 2081) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 2085) | public Object[] toArray() {
      method toDoubleArray (line 2088) | public double[] toDoubleArray() {
      method removeRange (line 2091) | public void removeRange(int startidx, int endidx) {
      method reduce (line 2096) | public Object reduce(IFn fn) { return ((IReduce)subList(0, nElems))....
      method reduce (line 2097) | public Object reduce(IFn fn, Object init) {
      method doubleReduction (line 2100) | public Object doubleReduction(IFn.ODO fn, Object init) {
      method indexComparator (line 2103) | public IntComparator indexComparator() {
      method indexComparator (line 2106) | public IntComparator indexComparator(Comparator c) {
      method sort (line 2109) | public void sort(Comparator<? super Object> c) {
      method shuffle (line 2112) | public void shuffle(Random r) {
      method binarySearch (line 2115) | @SuppressWarnings("unchecked")
      method sortIndirect (line 2119) | public int[] sortIndirect(Comparator c) {
      method doubleForEach (line 2122) | public void doubleForEach(DoubleConsumer c) {
      method move (line 2128) | public void move(int sidx, int eidx, int count) {
      method fill (line 2132) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 2136) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 2140) | public Object copyOf(int len) {
      method wrap (line 2143) | public static DoubleArrayList wrap(final double[] data, int nElems, ...
      method wrap (line 2148) | public static DoubleArrayList wrap(final double[] data, IPersistentM...
    method toList (line 2153) | public static IMutList<Object> toList(final double[] data, final int s...
    method toList (line 2156) | public static IMutList<Object> toList(final double[] data) { return to...
    class CharArraySubList (line 2158) | public static class CharArraySubList implements ILongArrayList {
      method CharArraySubList (line 2163) | public CharArraySubList(char[] d, int s, int len, IPersistentMap m) {
      method toString (line 2169) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 2170) | public boolean equals(Object other) {
      method hashCode (line 2173) | public int hashCode() { return hasheq(); }
      method getArraySection (line 2174) | public ArraySection getArraySection() { return new ArraySection(data...
      method size (line 2175) | public int size() { return dlen; }
      method set (line 2176) | public Character set(int idx, Object obj) {
      method get (line 2182) | public Character get(int idx) { return data[checkIndex(idx, dlen) + ...
      method getLong (line 2183) | public long getLong(int idx) { return data[checkIndex(idx, dlen) + s...
      method setLong (line 2184) | public void setLong(int idx, long obj) {
      method subList (line 2189) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 2193) | public IPersistentMap meta() { return meta; }
      method withMeta (line 2194) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 2197) | public Object[] toArray() {
      method asCharComparator (line 2204) | public static CharComparator asCharComparator(Comparator c) {
      method sort (line 2215) | @SuppressWarnings("unchecked")
      method shuffle (line 2227) | public void shuffle(Random r) {
      method binarySearch (line 2230) | @SuppressWarnings("unchecked")
      method reduce (line 2239) | public Object reduce(IFn rfn, Object init) {
      method fillRangeReducible (line 2245) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 2262) | public void move(int sidx, int eidx, int count) {
      method fill (line 2266) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 2270) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 2274) | public Object copyOf(int len) {
    method toList (line 2279) | public static IMutList<Object> toList(final char[] data, final int sid...
    method toList (line 2283) | public static IMutList<Object> toList(final char[] data) { return toLi...
    class BooleanArraySubList (line 2286) | public static class BooleanArraySubList implements IArrayList {
      method BooleanArraySubList (line 2292) | public BooleanArraySubList(boolean[] d, int s, int len, IPersistentM...
      method toString (line 2298) | public String toString() { return Transformables.sequenceToString(th...
      method equals (line 2299) | public boolean equals(Object other) {
      method hashCode (line 2302) | public int hashCode() { return hasheq(); }
      method getArraySection (line 2303) | public ArraySection getArraySection() { return new ArraySection(data...
      method size (line 2304) | public int size() { return dlen; }
      method getBoolean (line 2305) | public boolean getBoolean(int idx) { return data[checkIndex(idx, dle...
      method setBoolean (line 2306) | public void setBoolean(int idx, boolean obj) {
      method getLong (line 2309) | public long getLong(int idx) { return Casts.longCast(data[checkIndex...
      method setLong (line 2310) | public void setLong(int idx, long obj) {
      method get (line 2313) | public Object get(int idx) { return getBoolean(idx); }
      method set (line 2314) | public Object set(int idx, Object v) {
      method cloneList (line 2319) | public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfR...
      method subList (line 2320) | public IMutList<Object> subList(int ssidx, int seidx) {
      method meta (line 2324) | public IPersistentMap meta() { return meta; }
      method withMeta (line 2325) | public IObj withMeta(IPersistentMap m) {
      method toArray (line 2328) | public Object[] toArray() {
      method fillRangeReducible (line 2335) | public void fillRangeReducible(long startidx, Object v) {
      method move (line 2352) | public void move(int sidx, int eidx, int count) {
      method fill (line 2356) | public void fill(int ssidx, int seidx, Object v) {
      method copyOfRange (line 2360) | public Object copyOfRange(int ssidx, int seidx) {
      method copyOf (line 2364) | public Object copyOf(int len) {
    method toList (line 2369) | public static IMutList<Object> toList(final boolean[] data, final int ...
    method toList (line 2373) | public static IMutList<Object> toList(final boolean[] data) { return t...
    method toList (line 2376) | public static IMutList<Object> toList(Object obj, int sidx, int eidx, ...
    method toList (line 2403) | public static IMutList<Object> toList(Object obj) {
    method toList (line 2411) | @SuppressWarnings("unchecked")
    method iarange (line 2419) | public static int[] iarange(int start, int end, int step) {
    method larange (line 2431) | public static long[] larange(long start, long end, long step) {
    method darange (line 2441) | public static double[] darange(double start, double end, double step) {

FILE: java/ham_fisted/ArraySection.java
  class ArraySection (line 5) | public class ArraySection
    method ArraySection (line 10) | public ArraySection(Object ary, int _sidx, int _eidx) {
    method ArraySection (line 18) | public ArraySection(ArraySection other) {
    method size (line 21) | public int size() { return eidx - sidx; }
    method toString (line 22) | public String toString() {

FILE: java/ham_fisted/BatchReducer.java
  class BatchReducer (line 11) | public class BatchReducer implements IFnDef.O, ITypedReduce, Sequential,...
    method BatchReducer (line 17) | public BatchReducer(IFn batchSrc) {
    method reduce (line 23) | public Object reduce(IFn rfn, Object acc) {
    method invoke (line 40) | public Object invoke() {
    method iterator (line 48) | public Iterator iterator() {
    method forEach (line 55) | @SuppressWarnings("unchecked")

FILE: java/ham_fisted/BatchedList.java
  class BatchedList (line 5) | public class BatchedList implements IMutList, IDeref {
    class Link (line 12) | public static class Link {
      method Link (line 15) | public Link(Object[][] leaf) {
    method BatchedList (line 23) | public BatchedList() {
    method add (line 28) | public boolean add(Object obj) {
    method get (line 48) | public Object get(int idx) { throw new RuntimeException(); }
    method count (line 49) | public int count() { return count; }
    method size (line 50) | public int size() { return count; }
    method clear (line 51) | public void clear() {
    method deref (line 57) | public TreeList deref() {

FILE: java/ham_fisted/BiFunctions.java
  class BiFunctions (line 7) | public class BiFunctions {

FILE: java/ham_fisted/BlockSplitBloomFilter.java
  class BlockSplitBloomFilter (line 39) | public class BlockSplitBloomFilter {
    method BlockSplitBloomFilter (line 80) | public BlockSplitBloomFilter(int numBytes) {
    method bitset (line 86) | public byte[] bitset() { return bitset; }
    method BlockSplitBloomFilter (line 95) | public BlockSplitBloomFilter(byte[] bitset) {
    method initBitset (line 113) | private void initBitset(int numBytes) {
    method setMask (line 128) | private int[] setMask(int key) {
    method insertHash (line 147) | public void insertHash(long hash) {
    method findHash (line 163) | public boolean findHash(long hash) {
    method checkArgument (line 180) | private static void checkArgument(boolean arg, String message) {
    method optimalNumOfBits (line 190) | public static int optimalNumOfBits(long n, double p) {
    method getBitsetSize (line 210) | public int getBitsetSize() {
    method hash (line 215) | public static long hash(byte[] input) {
    method equals (line 220) | public boolean equals(Object object) {
    method canMergeFrom (line 232) | public boolean canMergeFrom(BlockSplitBloomFilter otherBloomFilter) {
    method merge (line 237) | public void merge(BlockSplitBloomFilter otherBloomFilter) throws IOExc...

FILE: java/ham_fisted/Casts.java
  class Casts (line 9) | public class Casts {
    method booleanCast (line 10) | public static boolean booleanCast(Object obj) {
    method booleanCast (line 23) | public static boolean booleanCast(long obj) {
    method booleanCast (line 26) | public static boolean booleanCast(double obj) {
    method booleanCast (line 29) | public static boolean booleanCast(float obj) {
    method booleanCast (line 32) | public static boolean booleanCast(boolean obj) {
    method charCast (line 35) | public static char charCast(double obj) {
    method charCast (line 41) | public static char charCast(float obj) {
    method charCast (line 47) | public static char charCast(long obj) {
    method charCast (line 50) | public static char charCast(Object obj) {
    method charLongCast (line 66) | public static long charLongCast(Object obj) {
    method longCast (line 69) | public static long longCast(Object obj) {
    method longCast (line 87) | public static long longCast(long obj) {
    method longCast (line 90) | public static long longCast(char obj) {
    method longCast (line 93) | public static long longCast(double obj) {
    method longCast (line 99) | public static long longCast(float obj) {
    method longCast (line 105) | public static long longCast(boolean obj) {
    method doubleCast (line 108) | public static double doubleCast(Object obj) {
    method doubleCast (line 119) | public static double doubleCast(long obj) {
    method doubleCast (line 122) | public static double doubleCast(double obj) {
    method doubleCast (line 125) | public static double doubleCast(float obj) {
    method doubleCast (line 128) | public static double doubleCast(boolean obj) {
    method floatCast (line 131) | public static float floatCast(float obj) { return obj; }
    method floatCast (line 132) | public static float floatCast(Object obj) {
    method intCast (line 135) | public static int intCast(int obj) { return obj; }
    method intCast (line 136) | public static int intCast(Object obj) {

FILE: java/ham_fisted/ChunkedList.java
  class ChunkedList (line 25) | public final class ChunkedList {
    method numChunks (line 34) | static final int numChunks(int capacity) {
    method lastChunkSize (line 38) | static final int lastChunkSize(int capacity) {
    method ChunkedList (line 47) | public ChunkedList(int initSize) {
    method ChunkedList (line 61) | public ChunkedList() {this(0);}
    method ChunkedList (line 63) | ChunkedList(Object[][] d, int c, int e, IPersistentMap m) {
    method ChunkedList (line 70) | ChunkedList(ChunkedList other, boolean shallow) {
    method create (line 86) | static ChunkedList create(boolean owning, IPersistentMap meta, Object....
    method clone (line 106) | ChunkedList clone(int startidx, int endidx, int extraAlloc, boolean de...
    method clone (line 146) | ChunkedList clone(int startidx, int endidx) { return clone(startidx, e...
    method clear (line 148) | void clear(int offset, int len) {
    method clear (line 166) | void clear() { clear(0, nElems); }
    method enlarge (line 168) | void enlarge(int cap) {
    method setValueRV (line 194) | final Object setValueRV(int idx, Object obj) {
    method setValue (line 201) | final void setValue(int idx, Object obj) {
    method getValue (line 204) | final Object getValue(final int idx) {
    method sublistCheck (line 208) | public static final void sublistCheck(long sidx, long eidx, long nElem...
    method indexCheck (line 223) | public static final int indexCheck(int nElems, int idx) {
    method indexCheck (line 229) | public static final int indexCheck(int startidx, int nElems, int idx) {
    method indexCheck (line 234) | public static final long indexCheck(long startidx, long nElems, long i...
    method wrapIndexCheck (line 240) | static final int wrapIndexCheck(int startidx, int nElems, int idx) {
    method checkIndexRange (line 247) | static public final void checkIndexRange(int startidx, int nElems, int...
    method checkIndexRange (line 261) | static public final void checkIndexRange(long startidx, long nElems, l...
    method add (line 275) | final boolean add(Object obj) {
    method widen (line 287) | final void widen(final int startidx, final int endidx) {
    method shorten (line 320) | final void shorten(int startidx, int endidx) {
    method add (line 351) | final void add(Object obj, int idx) {
    method conj (line 366) | final ChunkedList conj(int startidx, int endidx, Object obj) {
    method assoc (line 383) | final ChunkedList assoc(int startidx, int endidx, int idx, Object obj) {
    method pop (line 397) | final ChunkedList pop(int startidx, int endidx) {
    method size (line 412) | final int size() { return nElems; }
    method fillRange (line 414) | final void fillRange(int startidx, int endidx, Object v) {
    method fillRangeReduce (line 420) | final void fillRangeReduce(final int startidx, Object v) {
    method addRange (line 431) | final void addRange(int startidx, int endidx, Object v) {
    method fillArray (line 438) | final Object[] fillArray(int startidx, int endidx, Object[] retval) {
    method fillArray (line 458) | final Object[] fillArray(Object[] retval) {
    method toArray (line 462) | final Object[] toArray(int startidx, int endidx) {
    method toArray (line 466) | final Object[] toArray() {
    class CLIter (line 470) | static class CLIter implements Iterator {
      method CLIter (line 477) | public CLIter(int startidx, int endidx, Object[][] _data) {
      method advance (line 485) | final void advance() {
      method hasNext (line 493) | public final boolean hasNext() {
      method next (line 498) | public final Object next() {
    method iterator (line 510) | public Iterator iterator(int startidx, int endidx) {
    method iterator (line 514) | public Iterator iterator() {
    class RIterator (line 518) | static class RIterator implements Iterator {
      method RIterator (line 522) | public RIterator( int sidx, int eidx, Object[][] d) {
      method advance (line 528) | void advance() {
      method hasNext (line 531) | public final boolean hasNext() { return idx >= startidx; }
      method next (line 532) | public final Object next() {
    method riterator (line 541) | public Iterator riterator(int startidx, int endidx) {
    class ListIter (line 545) | static class ListIter<E> implements ListIterator<E> {
      method ListIter (line 552) | ListIter(int sidx, int eidx, Object[][] d) {
      method add (line 559) | public void add(E obj) { throw new RuntimeException("Unimplemented."...
      method remove (line 560) | public void remove() { throw new RuntimeException("Unimplemented."); }
      method hasNext (line 561) | public final boolean hasNext() { return idx < endidx; }
      method hasPrevious (line 562) | public final boolean hasPrevious() { return idx > startidx; }
      method next (line 563) | @SuppressWarnings("unchecked")
      method nextIndex (line 572) | public final int nextIndex() {
      method previous (line 575) | @SuppressWarnings("unchecked")
      method previousIndex (line 583) | public final int previousIndex() {
      method set (line 586) | @SuppressWarnings("unchecked")
    method listIterator (line 592) | <E> ListIterator<E> listIterator(int startidx, int endidx, E marker) {
    class ChunkedListSection (line 596) | static class ChunkedListSection {
      method size (line 600) | public int size() { return endidx - startidx; }
      method ChunkedListSection (line 601) | public ChunkedListSection(Object[][] cl, int sidx, int eidx) {
    type ChunkedListOwner (line 609) | interface ChunkedListOwner {
      method getChunkedList (line 610) | ChunkedListSection getChunkedList();
    method reduce (line 613) | Object reduce(final int startidx, final int endidx, final IFn f, final...
    method reduce (line 629) | Object reduce(final int startidx, final int endidx, IFn f) {
    method kvreduce (line 635) | Object kvreduce(int startidx, int endidx, IFn f, Object init) {
    method seq (line 643) | final ISeq seq(int startidx, int endidx) {
    method rseq (line 647) | final ISeq rseq(int startidx, int endidx) {
    method hasheq (line 651) | final int hasheq(int startidx, int endidx) {
    method equiv (line 661) | final boolean equiv(int sidx, int eidx, Object o) {
    method meta (line 702) | final IPersistentMap meta() { return meta; }
    method withMeta (line 703) | final ChunkedList withMeta(IPersistentMap m) {
    method indexOf (line 706) | final int indexOf(int startidx, int endidx, Object obj) {
    method lastIndexOf (line 714) | final int lastIndexOf(int startidx, int endidx, Object obj) {
    method contains (line 725) | final boolean contains(int startidx, int endidx, Object obj) {
    method containsAll (line 729) | final boolean containsAll(int startidx, int endidx, Collection<?> c) {

FILE: java/ham_fisted/CljHash.java
  class CljHash (line 19) | public class CljHash {
    method mapHashcode (line 21) | public static int mapHashcode(Map data) {
    method setHashcode (line 24) | public static int setHashcode(Set data) {
    method equiv (line 28) | public static boolean equiv(Object k1, Object k2) {
    method nonNullEquiv (line 36) | public static boolean nonNullEquiv(Object k1, Object k2) {
    method mapEquiv (line 54) | public static boolean mapEquiv(Map lhs, Object rhs) {
    method setEquiv (line 72) | public static boolean setEquiv(Set data, Object rhs) {
    class ListHasheqConsumer (line 86) | public static class ListHasheqConsumer implements java.util.function.C...
      method ListHasheqConsumer (line 89) | public ListHasheqConsumer() {
      method accept (line 93) | public void accept(Object obj) {
      method hash (line 97) | public int hash() {
    method listHasheq (line 102) | public static int listHasheq(List l) {
    method listEquiv (line 108) | public static boolean listEquiv(List l, Object rhs) {

FILE: java/ham_fisted/ConstList.java
  class ConstList (line 13) | public class ConstList implements IMutList<Object>, TypedList {
    method ConstList (line 17) | public ConstList(long _nElems, Object _v, IPersistentMap m) {
    method cloneList (line 22) | public IMutList cloneList() { return this; }
    method containedType (line 23) | public Class containedType() { return value != null ? value.getClass()...
    method create (line 24) | public static ConstList create(long nElems, Object value, IPersistentM...
    method size (line 33) | public int size() { return RT.intCast(nElems); }
    method get (line 34) | public Object get(int idx) {
    method subList (line 37) | public ConstList subList(long sidx, long eidx) {
    method subList (line 41) | public ConstList subList(int sidx, int eidx) {
    method sort (line 44) | public void sort(Comparable c) { }
    method immutSort (line 45) | public ConstList immutSort(Comparable c) { return this; }
    method ImmutSort (line 46) | public ConstList ImmutSort() { return this; }
    method reverse (line 47) | public ConstList reverse() { return this; }
    method sortIndirect (line 48) | public int[] sortIndirect() { return ArrayLists.iarange(0, size(), 1); }
    method toArray (line 49) | public Object[] toArray() {
    method toIntArray (line 54) | public int[] toIntArray() {
    method toLongArray (line 60) | public long[] toLongArray() {
    method toDoubleArray (line 66) | public double[] toDoubleArray() {
    method reindex (line 72) | public ConstList reindex(int[] indexes) {
    method immutShuffle (line 75) | public List immutShuffle(Random r) { return this; }
    method indexComparator (line 76) | public IntComparator indexComparator(Comparator c) {
    method meta (line 79) | public IPersistentMap meta() { return meta; }
    method withMeta (line 80) | public ConstList withMeta(IPersistentMap m) {
    class LongConstList (line 83) | public static class LongConstList extends ConstList implements LongMut...
      method LongConstList (line 85) | public LongConstList(long ne, long v, IPersistentMap m ) {
      method containedType (line 89) | public Class containedType() { return Long.TYPE; }
      method getLong (line 90) | public long getLong(int idx) { return lval; }
      method reduce (line 91) | public Object reduce(IFn rfn, Object init) { return LongMutList.supe...
    class DoubleConstList (line 93) | public static class DoubleConstList extends ConstList implements Doubl...
      method DoubleConstList (line 95) | public DoubleConstList(long ne, double v, IPersistentMap m ) {
      method containedType (line 99) | public Class containedType() { return Double.TYPE; }
      method getDouble (line 100) | public double getDouble(int idx) { return lval; }
      method reduce (line 101) | public Object reduce(IFn rfn, Object init) { return DoubleMutList.su...

FILE: java/ham_fisted/ConsumerAccumulators.java
  class ConsumerAccumulators (line 4) | public class ConsumerAccumulators {
    class DoubleConsumerAccumulator (line 5) | public static class DoubleConsumerAccumulator implements IFnDef.ODO  {
      method DoubleConsumerAccumulator (line 7) | public DoubleConsumerAccumulator(){}
      method invokePrim (line 8) | public Object invokePrim(Object acc, double val) {
    class LongConsumerAccumulator (line 13) | public static class LongConsumerAccumulator implements IFnDef.OLO  {
      method LongConsumerAccumulator (line 15) | public LongConsumerAccumulator(){}
      method invokePrim (line 16) | public Object invokePrim(Object acc, long val) {
    class ConsumerAccumulator (line 21) | public static class ConsumerAccumulator implements IFnDef.OOO  {
      method ConsumerAccumulator (line 23) | public ConsumerAccumulator(){}
      method invoke (line 24) | @SuppressWarnings("unchecked")

FILE: java/ham_fisted/Consumers.java
  class Consumers (line 14) | public class Consumers {
    type IDerefDoubleConsumer (line 15) | public interface IDerefDoubleConsumer extends IDeref, DoubleConsumer, ...
      method accept (line 17) | default void accept(Object v) { accept(Casts.doubleCast(v)); }
      method accept (line 18) | default void accept(double v) { acceptDouble(v); }
      method acceptDouble (line 19) | void acceptDouble(double v);
    type IDerefLongConsumer (line 21) | public interface IDerefLongConsumer extends IDeref, LongConsumer, Cons...
      method accept (line 23) | default void accept(Object v) { accept(Casts.longCast(v)); }
      method accept (line 24) | default void accept(long v) { acceptLong(v); }
      method acceptLong (line 25) | void acceptLong(long v);
    type IDerefConsumer (line 27) | public interface IDerefConsumer extends IDeref, Consumer {}
    type IDerefIndexedDoubleConsumer (line 28) | public interface IDerefIndexedDoubleConsumer extends IDeref, IndexedDo...
    type IDerefIndexedLongConsumer (line 29) | public interface IDerefIndexedLongConsumer extends IDeref, IndexedLong...
    type IDerefIndexedConsumer (line 30) | public interface IDerefIndexedConsumer extends IDeref, IndexedConsumer {}
    method asIndexedDoubleConsumer (line 31) | public static IndexedDoubleConsumer asIndexedDoubleConsumer(Object obj) {
    method asIndexedLongConsumer (line 36) | public static IndexedLongConsumer asIndexedLongConsumer(Object obj) {
    method asIndexedConsumer (line 41) | public static IndexedConsumer asIndexedConsumer(Object obj) {
    class IndexedDoubleConsumerConverter (line 46) | public static final class IndexedDoubleConsumerConverter implements ID...
      method IndexedDoubleConsumerConverter (line 49) | public IndexedDoubleConsumerConverter(long initIdx, IndexedDoubleCon...
      method acceptDouble (line 53) | public void acceptDouble(double v) {
      method deref (line 57) | public Object deref() { return ((IDeref)c).deref(); }
    method toDoubleConsumer (line 59) | public static DoubleConsumer toDoubleConsumer(long initIdx, IndexedDou...
    class IndexedLongConsumerConverter (line 62) | public static final class IndexedLongConsumerConverter implements IDer...
      method IndexedLongConsumerConverter (line 65) | public IndexedLongConsumerConverter(long initIdx, IndexedLongConsume...
      method acceptLong (line 69) | public void acceptLong(long v) {
      method deref (line 73) | public Object deref() { return ((IDeref)c).deref(); }
    method toLongConsumer (line 75) | public static LongConsumer toLongConsumer(long initIdx, IndexedLongCon...
    class IndexedConsumerConverter (line 79) | public static final class IndexedConsumerConverter implements IDerefCo...
      method IndexedConsumerConverter (line 82) | public IndexedConsumerConverter(long initIdx, IndexedConsumer cc) {
      method accept (line 86) | public void accept(Object v) {
      method deref (line 90) | public Object deref() { return ((IDeref)c).deref(); }
    method toConsumer (line 92) | public static Consumer toConsumer(long initIdx, IndexedConsumer c) {
    method map (line 96) | public static DoubleConsumer map(final DoubleUnaryOperator fn, final D...
    method map (line 106) | public static LongConsumer map(final LongUnaryOperator fn, final LongC...
    method map (line 116) | @SuppressWarnings("unchecked")
    method map (line 128) | public static IndexedDoubleConsumer map(final DoubleUnaryOperator fn, ...
    method map (line 138) | public static IndexedLongConsumer map(final LongUnaryOperator fn, fina...
    method map (line 148) | @SuppressWarnings("unchecked")
    method filter (line 160) | public static DoubleConsumer filter(final DoublePredicate pred, final ...
    method filter (line 171) | public static LongConsumer filter(final LongPredicate pred, final Long...
    method filter (line 182) | @SuppressWarnings("unchecked")
    method filter (line 195) | public static IndexedDoubleConsumer filter(final DoublePredicate pred,...
    method filter (line 206) | public static IndexedLongConsumer filter(final LongPredicate pred, fin...
    method filter (line 217) | @SuppressWarnings("unchecked")
    class IncConsumer (line 230) | public static class IncConsumer implements Consumer, Reducible, IDeref {
      method apply (line 232) | public IncConsumer apply(Object obj) { return new IncConsumer(); }
      method IncConsumer (line 235) | public IncConsumer(long v) { nElems = v;}
      method IncConsumer (line 236) | public IncConsumer() { this(0); }
      method accept (line 237) | public void accept(Object o) { ++nElems; }
      method inc (line 238) | public void inc() { ++nElems; }
      method setValue (line 239) | public void setValue(int v) { nElems = v;}
      method reduce (line 240) | public IncConsumer reduce(Reducible o) {
      method value (line 244) | public long value() { return nElems; }
      method deref (line 245) | public Object deref() { return nElems; }

FILE: java/ham_fisted/CtxIter.java
  class CtxIter (line 6) | public class CtxIter implements Iterator {
    type Ctx (line 7) | public static interface Ctx {
      method update (line 8) | public Ctx update();
      method valid (line 9) | public boolean valid();
      method val (line 10) | public Object val();
    method CtxIter (line 18) | public CtxIter(Supplier<Ctx> init) {
    method advance (line 23) | void advance() {
    method step (line 31) | public int step() { return step; }
    method ctx (line 32) | public Ctx ctx() { return ctx; }
    method hasNext (line 33) | public boolean hasNext() {
    method next (line 37) | public Object next() {

FILE: java/ham_fisted/DoubleMutList.java
  type DoubleMutList (line 14) | @SuppressWarnings("unchecked")
    method add (line 16) | default boolean add(Object obj) { addDouble(Casts.doubleCast(obj)); re...
    method addLong (line 17) | default void addLong(long obj) { addDouble(Casts.doubleCast(obj)); }
    method addDouble (line 18) | default void addDouble(double v) { throw new RuntimeException("Object ...
    method add (line 19) | default void add(int idx, int count, Object v) {
    method set (line 24) | @SuppressWarnings("unchecked")
    method setBoolean (line 26) | default void setBoolean(int idx, boolean obj) { setDouble(idx, obj ? 1...
    method setLong (line 27) | default void setLong(int idx, long obj) { setDouble(idx, (double)obj); }
    method get (line 28) | default Object get(int idx) { return getDouble(idx); }
    method getLong (line 29) | default long getLong(int idx) { return (long)getDouble(idx); }
    class DoubleSubList (line 30) | static class DoubleSubList extends IMutList.MutSubList<Object> impleme...
      method DoubleSubList (line 31) | @SuppressWarnings("unchecked")
      method reduce (line 35) | public Object reduce(IFn rfn, Object init) { return DoubleMutList.su...
    method subList (line 37) | default IMutList<Object> subList(int sidx, int eidx) {
    method addAllReducible (line 41) | default boolean addAllReducible(Object obj) {
    method fillRange (line 51) | default void fillRange(long startidx, final long endidx, Object v) {
    method fillRange (line 58) | default void fillRange(final long ss, List l) {
    method addRange (line 72) | default void addRange(int startidx, int endidx, Object v) {
    method indexComparator (line 78) | default IntComparator indexComparator() {
    method sort (line 85) | default void sort(Comparator<? super Object> c) {
    method shuffle (line 98) | default void shuffle(Random r) {
    method immutShuffle (line 101) | default List immutShuffle(Random r) {
    method reduce (line 107) | default Object reduce(final IFn rfn, Object init) {
    method doubleReduction (line 110) | default Object doubleReduction(IFn.ODO rfn, Object init) {
    method spliterator (line 116) | @SuppressWarnings("unchecked")

FILE: java/ham_fisted/FJTask.java
  class FJTask (line 8) | public class FJTask extends RecursiveTask {
    method FJTask (line 10) | public FJTask(Object c) {
    method compute (line 17) | public Object compute() { return c.deref(); }

FILE: java/ham_fisted/FMapEntry.java
  class FMapEntry (line 8) | public class FMapEntry<K,V> implements IMutList, Map.Entry<K,V> {
    method FMapEntry (line 13) | public FMapEntry(K _k, V _v) {
    method FMapEntry (line 19) | public FMapEntry(FMapEntry<K,V> e, IPersistentMap m) {
    method create (line 25) | public static <K,V> FMapEntry<K,V> create(K k, V v) {
    method equals (line 28) | public boolean equals(Object o) { return equiv(o); }
    method hashCode (line 29) | public int hashCode() { return hasheq(); }
    method hasheq (line 30) | public int hasheq() {
    method setValue (line 35) | public V setValue( Object v) { throw new RuntimeException("Cannot set ...
    method getKey (line 36) | public K getKey() { return k; }
    method key (line 37) | public Object key() { return k; }
    method getValue (line 38) | public V getValue() { return v; }
    method val (line 39) | public Object val() { return v; }
    method size (line 40) | public int size() { return 2; }
    method get (line 41) | public Object get(int idx) {
    method withMeta (line 46) | public FMapEntry<K,V> withMeta(IPersistentMap m) { return new FMapEntr...
    method meta (line 47) | public IPersistentMap meta() { return meta; }

FILE: java/ham_fisted/ForkJoinPatterns.java
  class ForkJoinPatterns (line 10) | public class ForkJoinPatterns {
    method ForkJoinPatterns (line 11) | private ForkJoinPatterns(){}
    method invoke (line 15) | public Object invoke() {
    method parallelIndexGroups (line 20) | public static Iterable parallelIndexGroups(long nElems, IFn bodyFn, Pa...
    method invoke (line 25) | public Object invoke() {
    method pmap (line 30) | public static Iterable pmap(ParallelOptions options, IFn bodyFn, Objec...
    method invoke (line 35) | public Object invoke() {
    method parallelSpliteratorReduce (line 39) | public static Object parallelSpliteratorReduce(IFn initValFn, IFn rfn,...

FILE: java/ham_fisted/HashBase.java
  class HashBase (line 18) | public class HashBase implements IMeta {
    method HashBase (line 26) | public HashBase(float loadFactor, int initialCapacity,
    method HashBase (line 38) | public HashBase(HashBase other, IPersistentMap m) {
    method capacity (line 47) | public int capacity() { return capacity; }
    method size (line 48) | public int size() { return length; }
    method count (line 49) | public int count() { return length; }
    method hash (line 51) | protected int hash(Object k) {
    method equals (line 57) | protected boolean equals(Object lhs, Object rhs) {
    method inc (line 63) | protected void inc(HashNode lf) { ++this.length; }
    method dec (line 64) | protected void dec(HashNode lf) { --this.length; }
    method modify (line 65) | protected void modify(HashNode lf) {}
    method newNode (line 66) | protected HashNode newNode(Object key, int hc, Object val) {
    method checkResize (line 70) | Object checkResize(Object rv) {
    method clear (line 123) | public void clear() {
    method meta (line 132) | public IPersistentMap meta() { return meta; }
    class HTIter (line 133) | static class HTIter implements Iterator {
      method HTIter (line 139) | HTIter(HashNode[] data, Function<Map.Entry,Object> fn) {
      method advance (line 147) | void advance() {
      method hasNext (line 155) | public boolean hasNext() { return l != null; }
      method next (line 156) | public Object next() {
    class HTSpliterator (line 162) | static class HTSpliterator implements Spliterator, ITypedReduce {
      method HTSpliterator (line 169) | public HTSpliterator(HashNode[] d, int len, Function<Map.Entry,Objec...
      method HTSpliterator (line 177) | public HTSpliterator(HashNode[] d, int sidx, int eidx, int es, Funct...
      method trySplit (line 185) | public HTSpliterator trySplit() {
      method characteristics (line 196) | public int characteristics() { return Spliterator.DISTINCT | Spliter...
      method estimateSize (line 197) | public long estimateSize() { return estimateSize; }
      method getExactSizeIfKnown (line 198) | public long getExactSizeIfKnown() { return estimateSize(); }
      method tryAdvance (line 199) | @SuppressWarnings("unchecked")
      method reduce (line 216) | public Object reduce(IFn rfn, Object acc) {
    method containsNodeKey (line 230) | final boolean containsNodeKey(Object key) {

FILE: java/ham_fisted/HashMap.java
  class HashMap (line 32) | public class HashMap extends HashBase implements IMap, MapSetOps, Update...
    method HashMap (line 34) | public HashMap(float loadFactor, int initialCapacity,
    method HashMap (line 39) | public HashMap() {
    method HashMap (line 42) | public HashMap(IPersistentMap m) {
    method HashMap (line 45) | public HashMap(HashMap other, IPersistentMap m) {
    method shallowClone (line 49) | public HashMap shallowClone() {
    method clone (line 52) | public HashMap clone() {
    method hashCode (line 63) | public int hashCode() {
    method hasheq (line 66) | public int hasheq() {
    method equals (line 69) | public  boolean equals(Object o) {
    method equiv (line 72) | public boolean equiv(Object o) {
    method size (line 75) | public int size() { return this.length; }
    method isEmpty (line 76) | public boolean isEmpty() { return this.length == 0; }
    method toString (line 77) | public String toString() {
    method put (line 92) | public Object put(Object key, Object val) {
    method putAll (line 113) | public void putAll(Map other) {
    method getOrDefault (line 136) | public Object getOrDefault(Object key, Object dv) {
    method get (line 144) | public Object get(Object key) {
    method entryAt (line 152) | public IMapEntry entryAt(Object key) {
    method containsKey (line 160) | public boolean containsKey(Object key) {
    method compute (line 163) | @SuppressWarnings("unchecked")
    method computeIfAbsent (line 190) | @SuppressWarnings("unchecked")
    method removeHashNode (line 214) | Object removeHashNode (HashNode e, HashNode lastNode, int loc) {
    method remove (line 223) | public Object remove(Object key) {
    method reduce (line 235) | public Object reduce(IFn rfn, Object acc) {
    method kvreduce (line 247) | public Object kvreduce(IFn rfn, Object acc) {
    method parallelReduction (line 259) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
    method replaceAll (line 263) | @SuppressWarnings("unchecked")
    class HashSetKeySet (line 285) | public static class HashSetKeySet extends MapKeySet implements SetOps {
      method HashSetKeySet (line 286) | public HashSetKeySet(HashMap hm) { super(hm); }
      method union (line 287) | public PersistentHashSet union(Collection c) {
      method intersection (line 290) | public PersistentHashSet intersection(Set c) {
      method difference (line 293) | public PersistentHashSet difference(Set c) {
    method keySet (line 298) | public Set keySet() {
    method hashMapUnion (line 304) | @SuppressWarnings("unchecked")
    method reduceUnion (line 334) | @SuppressWarnings("unchecked")
    method kvReduceUnion (line 360) | @SuppressWarnings("unchecked")
    method entrySetUnion (line 384) | @SuppressWarnings("unchecked")
    method union (line 413) | public static HashMap union(HashMap rv, Map o, BiFunction bfn) {
    method union (line 426) | @SuppressWarnings("unchecked")
    method intersection (line 430) | @SuppressWarnings("unchecked")
    method intersection (line 449) | public HashMap intersection(Map o, BiFunction bfn) {
    method intersection (line 453) | public static HashMap intersection(HashMap rv, Set o) {
    method intersection (line 468) | public HashMap intersection(Set o) {
    method difference (line 473) | @SuppressWarnings("unchecked")
    method difference (line 489) | public HashMap difference(Collection o) {
    method updateValues (line 493) | @SuppressWarnings("unchecked")
    method updateValues (line 509) | public HashMap updateValues(BiFunction valueMap) {
    method updateValue (line 512) | @SuppressWarnings("unchecked")
    method updateValue (line 525) | public HashMap updateValue(Object k, Function fn) {
    method iterator (line 529) | public Iterator iterator(Function<Map.Entry,Object> leafFn) {
    method spliterator (line 532) | public Spliterator spliterator(Function<Map.Entry,Object> leafFn) { re...

FILE: java/ham_fisted/HashNode.java
  class HashNode (line 8) | public class HashNode implements Map.Entry, IMutList, IMapEntry {
    method HashNode (line 16) | public HashNode(HashBase _owner, Object _k, int hc, Object _v, HashNod...
    method HashNode (line 24) | public HashNode(HashBase _owner, Object _k, int hc, Object _v) {
    method HashNode (line 27) | public HashNode(HashBase _owner, Object _k, int hc) {
    method HashNode (line 31) | HashNode(HashBase _owner, HashNode prev) {
    method setOwner (line 38) | public HashNode setOwner(HashBase nowner) {
    method clone (line 43) | public HashNode clone(HashBase nowner) {
    method key (line 49) | public final Object key() { return k; }
    method val (line 50) | public final Object val() { return v; }
    method getKey (line 51) | public final Object getKey() { return k; }
    method getValue (line 52) | public final Object getValue() { return v; }
    method setValue (line 53) | public Object setValue(Object vv) { Object rv = v; v = vv; return rv; }
    method size (line 54) | public final int size() { return 2; }
    method get (line 55) | public final Object get(int idx) {
    method assoc (line 60) | public HashNode assoc(HashBase nowner, Object _k, int hash, Object _v) {
    method dissoc (line 73) | public HashNode dissoc(HashBase nowner, Object _k) {

FILE: java/ham_fisted/HashProvider.java
  type HashProvider (line 7) | public interface HashProvider {
    method hash (line 8) | public default int hash(Object obj) {
    method equals (line 11) | public default boolean equals(Object lhs, Object rhs) {

FILE: java/ham_fisted/HashProviders.java
  class HashProviders (line 7) | public class HashProviders {
    method hash (line 13) | public int hash(Object obj) {
    method equals (line 16) | public boolean equals(Object lhs, Object rhs) {
    method hash (line 23) | public int hash(Object k) {
    method equals (line 29) | public boolean equals(Object lhs, Object rhs) {

FILE: java/ham_fisted/HashSet.java
  class HashSet (line 15) | public class HashSet extends HashBase implements ISet, SetOps {
    method HashSet (line 17) | public HashSet(float loadFactor, int initialCapacity,
    method HashSet (line 22) | public HashSet() {
    method HashSet (line 25) | public HashSet(IPersistentMap m) {
    method HashSet (line 28) | public HashSet(HashBase other, IPersistentMap m) {
    method HashSet (line 31) | public HashSet(HashBase other) {
    method shallowClone (line 34) | public HashSet shallowClone() {
    method clone (line 37) | public HashSet clone() {
    method hashCode (line 48) | public int hashCode() {
    method hasheq (line 51) | public int hasheq() {
    method equals (line 54) | public  boolean equals(Object o) {
    method equiv (line 57) | public boolean equiv(Object o) {
    method add (line 60) | public boolean add(Object key) {
    method addAllReduceGeneric (line 80) | public void addAllReduceGeneric(IReduceInit r) {
    method addAll (line 99) | public boolean addAll(Collection c) {
    method remove (line 147) | public boolean remove(Object key) {
    method contains (line 164) | public boolean contains(Object key) {
    method iterator (line 167) | public Iterator iterator() {
    method spliterator (line 170) | public Spliterator spliterator() {
    method reduce (line 173) | public Object reduce(IFn rfn, Object acc) {
    method union (line 185) | public static HashSet union(HashSet rv, Collection rhs) {
    method union (line 225) | public HashSet union(Collection rhs) {
    method intersection (line 229) | public static HashSet intersection(HashSet rv, Set rhs) {
    method intersection (line 244) | public HashSet intersection(Set rhs) {
    method difference (line 248) | public static HashSet difference(HashSet rv, Set rhs) {
    method difference (line 278) | public HashSet difference(Set rhs) {

FILE: java/ham_fisted/IAMapEntry.java
  type IAMapEntry (line 7) | public interface IAMapEntry extends Map.Entry, IMutList, IMapEntry {
    method setValue (line 8) | default Object setValue(Object v) { throw new UnsupportedOperationExce...
    method key (line 9) | default Object key() { return getKey(); }
    method val (line 10) | default Object val() { return getValue(); }
    method size (line 11) | default int size() { return 2; }
    method get (line 12) | default Object get(int idx) {

FILE: java/ham_fisted/IAPersistentMap.java
  type IAPersistentMap (line 8) | interface IAPersistentMap extends Map, IEditableCollection, IPersistentM...
    method count (line 9) | default int count() { return size(); }
    method cons (line 10) | default IPersistentMap cons(Object v) { return (IPersistentMap)(asTran...
    method assocEx (line 11) | default IPersistentMap assocEx(Object key, Object val) {
    method assoc (line 16) | default IPersistentMap assoc(Object key, Object val) {
    method without (line 19) | default IPersistentMap without(Object key) {
    method asTransient (line 22) | ITransientMap asTransient();

FILE: java/ham_fisted/IAPersistentSet.java
  type IAPersistentSet (line 9) | public interface IAPersistentSet extends ISet, IEditableCollection, IPer...
    method count (line 10) | default int count() { return size(); }
    method get (line 11) | default Object get(Object o) { return contains(o) ? o : null; }
    method cons (line 12) | default IPersistentSet cons(Object o) {
    method disjoin (line 15) | default IPersistentSet disjoin(Object o) {
    method asTransient (line 18) | ITransientSet asTransient();

FILE: java/ham_fisted/IATransientMap.java
  type IATransientMap (line 11) | public interface IATransientMap extends ITransientMap, ITransientAssocia...
    method conjVal (line 12) | default ITransientMap conjVal(Object val) {
    method conj (line 27) | default ITransientMap conj(Object val) {

FILE: java/ham_fisted/IATransientSet.java
  type IATransientSet (line 7) | public interface IATransientSet extends ITransientSet {
    method get (line 8) | default Object get(Object o) { return contains(o) ? o : null; }

FILE: java/ham_fisted/ICollectionDef.java
  type ICollectionDef (line 9) | public interface ICollectionDef<E> extends Collection<E> {
    method add (line 10) | default boolean add(E e) { throw new UnsupportedOperationException("Un...
    method addAll (line 11) | default boolean addAll(Collection<? extends E> c) { throw new Unsuppor...
    method clear (line 12) | default void clear() { throw new UnsupportedOperationException("Unimpl...
    method contains (line 14) | default boolean contains(Object o) {
    method containsAll (line 20) | default boolean containsAll(Collection<?> c) { throw new UnsupportedOp...
    method isEmpty (line 22) | default boolean isEmpty() { return iterator().hasNext() == false; }
    method remove (line 24) | default boolean remove(Object o) { throw new UnsupportedOperationExcep...
    method removeAll (line 26) | default boolean removeAll(Collection<?> c) { throw new UnsupportedOper...
    method removeIf (line 27) | default boolean removeIf(Predicate<? super E> filter) { throw new Unsu...
    method retainAll (line 28) | default boolean retainAll(Collection<?> c) { throw new UnsupportedOper...
    method toArray (line 29) | default Object[] toArray() { return ArrayLists.toArray(this); }
    method toArray (line 30) | default <T> T[] toArray(T[] d) {

FILE: java/ham_fisted/IFnDef.java
  type IFnDef (line 30) | public interface IFnDef extends IFn
    method call (line 33) | default Object call() {
    method run (line 37) | default void run(){
    method invoke (line 41) | default Object invoke() {
    method invoke (line 45) | default Object invoke(Object arg1) {
    method invoke (line 49) | default Object invoke(Object arg1, Object arg2) {
    method invoke (line 53) | default Object invoke(Object arg1, Object arg2, Object arg3) {
    method invoke (line 57) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 61) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 65) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 69) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 74) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 79) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 84) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 89) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 94) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 99) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 105) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 111) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 117) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 123) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 129) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 135) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 141) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method invoke (line 149) | default Object invoke(Object arg1, Object arg2, Object arg3, Object ar...
    method applyTo (line 157) | default Object applyTo(ISeq arglist) {
    method asRandomAccess (line 161) | static public List asRandomAccess(Object arglist) {
    method ifaceApplyToHelper (line 169) | @SuppressWarnings("unchecked")
    method throwArity (line 268) | default Object throwArity(int n){
    type O (line 273) | public interface O extends IFnDef, Supplier {
      method get (line 274) | default Object get() { return invoke(); }
    type D (line 277) | public interface D extends IFnDef, DoubleSupplier, Supplier, IFn.D {
      method getAsDouble (line 278) | default double getAsDouble() { return invokePrim(); }
      method get (line 279) | default Object get() { return invokePrim(); }
      method invoke (line 280) | default Object invoke() { return invokePrim(); }
    type L (line 283) | public interface L extends IFnDef, DoubleSupplier, Supplier, IFn.L {
      method getAsLong (line 284) | default long getAsLong() { return invokePrim(); }
      method get (line 285) | default Object get() { return invokePrim(); }
      method invoke (line 286) | default Object invoke() { return invokePrim(); }
    type OO (line 289) | public interface OO extends IFnDef, UnaryOperator {
      method apply (line 290) | default Object apply(Object arg) { return invoke(arg); }
    type OOO (line 293) | public interface OOO extends IFnDef, BinaryOperator {
      method apply (line 294) | default Object apply(Object l, Object r) { return invoke(l,r); }
    type LO (line 297) | public interface LO extends IFnDef, IFn.LO, LongFunction {
      method invoke (line 298) | default Object invoke(Object arg) {
      method apply (line 301) | default Object apply(long v) { return invokePrim(v); }
    type LongPredicate (line 303) | public interface LongPredicate extends IFnDef, IFn.LO, LongFunction,
      method invokePrim (line 305) | default Object invokePrim(long arg) {
      method invoke (line 308) | default Object invoke(Object arg) {
      method apply (line 311) | default Object apply(long v) { return test(v); }
    type LL (line 313) | public interface LL extends IFnDef, IFn.LL, LongUnaryOperator {
      method invoke (line 314) | default Object invoke(Object arg) {
      method applyAsLong (line 317) | default long applyAsLong(long v) {
    type OL (line 321) | public interface OL extends IFnDef, IFn.OL, ToLongFunction {
      method invoke (line 322) | default Object invoke(Object arg) {
      method applyAsLong (line 325) | default long applyAsLong(Object v) { return invokePrim(v); }
    type DO (line 327) | public interface DO extends IFnDef, IFn.DO, DoubleFunction {
      method invoke (line 328) | default Object invoke(Object arg) {
      method apply (line 331) | default Object apply(double v) { return invokePrim(v); }
    type DoublePredicate (line 333) | public interface DoublePredicate extends IFnDef, IFn.DO, DoubleFunction,
      method invoke (line 335) | default Object invoke(Object arg) {
      method invokePrim (line 338) | default Object invokePrim(double arg) {
      method apply (line 341) | default Object apply(double v) { return test(v); }
      method negate (line 342) | default DoublePredicate negate() {
    type DD (line 351) | public interface DD extends IFnDef, IFn.DD, DoubleUnaryOperator {
      method invoke (line 352) | default Object invoke(Object arg) {
      method applyAsDouble (line 355) | default double applyAsDouble(double v) {
    type OD (line 359) | public interface OD extends IFnDef, IFn.OD, ToDoubleFunction {
      method invoke (line 360) | default Object invoke(Object arg) {
      method applyAsDouble (line 363) | default double applyAsDouble(Object v) { return invokePrim(v); }
    type LD (line 365) | public interface LD extends IFnDef, IFn.LD {
      method invoke (line 366) | default Object invoke(Object arg) {
    type DL (line 370) | public interface DL extends IFnDef, IFn.DL {
      method invoke (line 371) | default Object invoke(Object arg) {
    type Predicate (line 375) | @SuppressWarnings("unchecked")
      method invoke (line 377) | default Object invoke(Object v) { return test(v); }
      method apply (line 378) | default Object apply(Object arg) { return test(arg); }
    type DDD (line 380) | public interface DDD extends IFnDef, IFn.DDD, DoubleBinaryOperator {
      method invoke (line 381) | default Object invoke(Object lhs, Object rhs) {
      method applyAsDouble (line 384) | default double applyAsDouble(double l, double r) {
    type LLL (line 388) | public interface LLL extends IFnDef, IFn.LLL, LongBinaryOperator {
      method invoke (line 389) | default Object invoke(Object lhs, Object rhs) {
      method applyAsLong (line 392) | default long applyAsLong(long l, long r) {
    type ODO (line 396) | public interface ODO extends IFnDef, IFn.ODO {
      method invoke (line 397) | default Object invoke(Object lhs, Object rhs) {
    type OLO (line 401) | public interface OLO extends IFnDef, IFn.OLO {
      method invoke (line 402) | default Object invoke(Object lhs, Object rhs) {
    type LLO (line 406) | public interface LLO extends IFnDef, IFn.LLO {
      method invoke (line 407) | default Object invoke(Object l, Object r) {
    type OLOO (line 412) | public interface OLOO extends IFnDef, IFn.OLOO {
      method invoke (line 413) | default Object invoke(Object acc, Object idx, Object v) {
    type OLDO (line 417) | public interface OLDO extends IFnDef, IFn.OLDO {
      method invoke (line 418) | default Object invoke(Object acc, Object idx, Object v) {
    type OLLO (line 422) | public interface OLLO extends IFnDef, IFn.OLLO {
      method invoke (line 423) | default Object invoke(Object acc, Object idx, Object v) {
    type DDDD (line 427) | public interface DDDD extends IFnDef, IFn.DDDD {
      method invoke (line 428) | default Object invoke (Object a, Object b, Object c) {
    type LLLL (line 434) | public interface LLLL extends IFnDef, IFn.LLLL {
      method invoke (line 435) | default Object invoke (Object a, Object b, Object c) {

FILE: java/ham_fisted/IMap.java
  type IMap (line 26) | public interface IMap extends Map, ITypedReduce, ILookup, IFnDef, Iterab...
    method iterator (line 29) | Iterator iterator(Function<Map.Entry, Object> fn);
    method spliterator (line 30) | default Spliterator spliterator(Function<Map.Entry, Object> fn) {
    method keyIterator (line 33) | default Iterator keyIterator() { return iterator((k)->k.getKey()); }
    method valIterator (line 34) | default Iterator valIterator() { return iterator((k)->k.getValue()); }
    method entryIterator (line 35) | default Iterator entryIterator() { return iterator((k)->k); }
    method iterator (line 36) | default Iterator iterator() { return entryIterator(); }
    method putAll (line 37) | @SuppressWarnings("unchecked")
    method containsValue (line 45) | default boolean containsValue(Object val) {
    method valAt (line 48) | default Object valAt(Object k) { return get(k); }
    method valAt (line 49) | @SuppressWarnings("unchecked")
    method invoke (line 51) | default Object invoke(Object k) { return get(k); }
    method invoke (line 52) | @SuppressWarnings("unchecked")
    method isEmpty (line 54) | default boolean isEmpty() { return this.size() == 0; }
    method forEach (line 55) | @SuppressWarnings("unchecked")
    method count (line 59) | default int count() { return size(); }
    method kvreduce (line 60) | default Object kvreduce(IFn f, Object init) {
    method seq (line 68) | default ISeq seq() {
    class MapKeySet (line 71) | public static class MapKeySet extends AbstractSet implements ITypedRed...
      method MapKeySet (line 73) | public MapKeySet(IMap data) { this.data = data; }
      method size (line 74) | public int size() { return data.size(); }
      method count (line 75) | public int count() { return data.size(); }
      method contains (line 76) | public boolean contains(Object k) { return data.containsKey(k); }
      method iterator (line 77) | public Iterator iterator() { return data.keyIterator(); }
      method spliterator (line 78) | public Spliterator spliterator() { return data.spliterator( (k)->k.g...
      method clear (line 79) | public void clear() { data.clear(); }
      method wrapRfn (line 80) | static IFn wrapRfn(IFn rfn) { return new IFnDef() {
      method reduce (line 86) | public Object reduce(IFn rfn, Object acc) {
      method parallelReduction (line 89) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
      method forEach (line 94) | @SuppressWarnings("unchecked")
      method invoke (line 103) | public Object invoke(Object k) { return data.containsKey(k) ? k : nu...
    method keySet (line 105) | default Set keySet() {
    class MapEntrySet (line 108) | public static class MapEntrySet extends AbstractSet implements ITypedR...
      method MapEntrySet (line 110) | public MapEntrySet(IMap data) { this.data = data; }
      method size (line 111) | public int size() { return data.size(); }
      method count (line 112) | public int count() { return data.size(); }
      method contains (line 113) | public boolean contains(Object k) {
      method iterator (line 118) | public Iterator iterator() { return data.entryIterator(); }
      method spliterator (line 119) | public Spliterator spliterator() { return data.spliterator( (k)->k ); }
      method clear (line 120) | public void clear() { data.clear(); }
      method reduce (line 121) | public Object reduce(IFn rfn, Object acc) {
      method parallelReduction (line 124) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
      method forEach (line 129) | @SuppressWarnings("unchecked")
      method invoke (line 133) | public Object invoke(Object k) { return contains(k); }
    method entrySet (line 135) | default Set entrySet() {
    class ValueCollection (line 138) | public static class ValueCollection  extends AbstractCollection implem...
      method ValueCollection (line 140) | public ValueCollection(IMap data) { this.data = data;}
      method size (line 141) | public final int size() { return data.size(); }
      method count (line 142) | public int count() { return data.size(); }
      method clear (line 143) | public final void clear() {
      method iterator (line 146) | public final Iterator iterator() {
      method spliterator (line 149) | @SuppressWarnings("unchecked")
      method wrapRfn (line 153) | public static IFn wrapRfn(IFn val) {
      method reduce (line 160) | public Object reduce(IFn rfn, Object acc) {
      method parallelReduction (line 163) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
      method forEach (line 168) | @SuppressWarnings("unchecked")
    method values (line 178) | default Collection values() {

FILE: java/ham_fisted/IMutList.java
  type IMutList (line 61) | public interface IMutList<E>
    method cloneList (line 67) | default IMutList cloneList() { return (IMutList)ArrayLists.toList(toAr...
    method clear (line 68) | default void clear() { throw new UnsupportedOperationException("Unimpl...
    method add (line 69) | default boolean add(E v) { throw new UnsupportedOperationException("Un...
    method add (line 70) | default void add(int idx, E v) {
    method add (line 73) | default void add(int idx, int count, E v) {
    method addLong (line 81) | @SuppressWarnings("unchecked")
    method addDouble (line 83) | @SuppressWarnings("unchecked")
    method removeRange (line 85) | default void removeRange(long startidx, long endidx) {
    method fillRange (line 92) | @SuppressWarnings("unchecked")
    method fillRangeReducible (line 102) | @SuppressWarnings("unchecked")
    method remove (line 116) | default E remove(int idx) {
    method remove (line 121) | default boolean remove(Object o) {
    method addAll (line 128) | default boolean addAll(Collection<? extends E> c) {
    method addAllReducible (line 131) | @SuppressWarnings("unchecked")
    method addAll (line 142) | default boolean addAll(int idx, Collection<? extends E> c) {
    method removeAll (line 152) | default boolean removeAll(Collection<?> c) {
    method retainAll (line 167) | default boolean retainAll(Collection<?> c) {
    class MutSubList (line 183) | public static class MutSubList<E> implements IMutList<E> {
      method MutSubList (line 188) | public MutSubList(IMutList<E> list, int ss, int ee) {
      method size (line 194) | public int size() { return nElems; }
      method get (line 195) | public E get(int idx) {
      method getLong (line 199) | public long getLong(int idx) {
      method getDouble (line 203) | public double getDouble(int idx) {
      method set (line 207) | @SuppressWarnings("unchecked")
      method setLong (line 212) | public void setLong(int idx, long v) {
      method setDouble (line 216) | public void setDouble(int idx, double v) {
      method reduce (line 220) | public Object reduce(IFn rfn, Object init) {
      method subList (line 227) | @SuppressWarnings("unchecked")
      method meta (line 234) | public IPersistentMap meta() { return list.meta(); }
      method withMeta (line 235) | @SuppressWarnings("unchecked")
    method subList (line 241) | @SuppressWarnings("unchecked")
    method indexOf (line 250) | default int indexOf(Object o) {
    method lastIndexOf (line 257) | default int lastIndexOf(Object o) {
    method contains (line 267) | default boolean contains(Object o) {
    method isEmpty (line 270) | default boolean isEmpty() { return size() == 0; }
    method compareTo (line 272) | default int compareTo(Object o) {
    class ListIter (line 288) | public static class ListIter<E> implements ListIterator<E> {
      method ListIter (line 292) | ListIter(List<E> ls, int _idx){list = ls; idx = _idx; previdx = _idx;}
      method hasNext (line 293) | public final boolean hasNext() {
      method hasPrevious (line 296) | public final boolean hasPrevious() {
      method next (line 299) | public final E next() {
      method previous (line 307) | public final E previous() {
      method nextIndex (line 314) | public final int nextIndex() {
      method previousIndex (line 317) | public final int previousIndex() {
      method remove (line 320) | public final void remove() {
      method set (line 323) | public final void set(E e) {
      method add (line 326) | public final void add(E e) {
    method listIterator (line 330) | default ListIterator<E> listIterator(int idx) {
    method listIterator (line 335) | default ListIterator<E> listIterator() {
    method iterator (line 338) | default Iterator<E> iterator() { return listIterator(0); }
    class RIter (line 339) | public class RIter<E> implements Iterator<E> {
      method RIter (line 342) | public RIter(List<E> ls) { list = ls; idx = 0; }
      method hasNext (line 343) | public final boolean hasNext() { return idx < list.size(); }
      method next (line 344) | public final E next() {
    method riterator (line 352) | default Iterator<E> riterator() { return new RIter<E>(this); }
    method spliterator (line 353) | default Spliterator<E> spliterator() {
    method fillArray (line 356) | default Object[] fillArray(Object[] data) {
    method toArray (line 365) | default Object[] toArray() {
    method toArray (line 368) | default <T> T[] toArray(T[] marker) {
    method toNativeArray (line 373) | default Object toNativeArray() {
    method toIntArray (line 376) | default int[] toIntArray() {
    method toLongArray (line 381) | default long[] toLongArray() {
    method toFloatArray (line 386) | default float[] toFloatArray() {
    method toDoubleArray (line 391) | default double[] toDoubleArray() {
    method indexComparator (line 396) | @SuppressWarnings("unchecked")
    method indexComparator (line 404) | @SuppressWarnings("unchecked")
    method sortIndirect (line 443) | @SuppressWarnings("unchecked")
    method nth (line 460) | default Object nth(int idx) {
    method nth (line 466) | default Object nth(int idx, Object notFound) {
    method set (line 472) | default E set(int idx, E v) { throw new UnsupportedOperationException(...
    method setLong (line 473) | @SuppressWarnings("unchecked")
    method setDouble (line 475) | @SuppressWarnings("unchecked")
    method getLong (line 477) | default long getLong(int idx) { return Casts.longCast(get(idx)); }
    method getDouble (line 478) | default double getDouble(int idx) {
    method accPlusLong (line 482) | default void accPlusLong(int idx, long val) {
    method accPlusDouble (line 485) | default void accPlusDouble(int idx, double val) {
    method invoke (line 489) | default Object invoke(Object idx) {
    method invoke (line 492) | default Object invoke(Object idx, Object notFound) {
    method valAt (line 497) | default Object valAt(Object idx) {
    method valAt (line 500) | default Object valAt(Object idx, Object def) {
    method entryAt (line 503) | default IMapEntry entryAt(Object key) {
    method containsAll (line 512) | @SuppressWarnings("unimplemented")
    method containsKey (line 524) | default boolean containsKey(Object key) {
    method count (line 533) | default int count() { return size(); }
    method length (line 534) | default int length() { return size(); }
    method reduce (line 536) | default Object reduce(IFn f) {
    method reduce (line 547) | default Object reduce(IFn f, Object init) {
    method kvreduce (line 555) | default Object kvreduce(IFn f, Object init) {
    method parallelReduction (line 562) | default Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
    method forEach (line 567) | @SuppressWarnings("unchecked")
    method hasheq (line 571) | default int hasheq() {
    method equiv (line 574) | default boolean equiv(Object other) {
    method sublistAsChunk (line 578) | public static IChunk sublistAsChunk(List data, int sidx) {
    method inplaceSublistSeq (line 609) | public static IChunkedSeq inplaceSublistSeq(List l, int sidx, int eidx) {
    method inplaceSublistSeq (line 624) | default IChunkedSeq inplaceSublistSeq() {
    method copyingArraySeq (line 628) | public static IChunkedSeq copyingArraySeq(List l, int sidx, int eidx) {
    method copyingArraySeq (line 642) | default IChunkedSeq copyingArraySeq() {
    method seq (line 645) | default ISeq seq() { return copyingArraySeq(); }
    method rseq (line 646) | default ISeq rseq() {
    method meta (line 650) | default IPersistentMap meta() { return null; }
    method withMeta (line 651) | default IObj withMeta(IPersistentMap meta ) { throw new UnsupportedOpe...
    method sort (line 653) | @SuppressWarnings("unchecked")
    method shuffle (line 668) | default void shuffle(Random r) {
    method reindex (line 671) | default List reindex(int[] indexes) {
    method immutShuffle (line 674) | default List immutShuffle(Random r) {
    method reverse (line 679) | default List reverse() {
    method binarySearch (line 682) | @SuppressWarnings("unchecked")
    method binarySearch (line 695) | default int binarySearch(E v) { return binarySearch(v, null); }
    method immut (line 696) | default IPersistentVector immut() { return ArrayImmutList.create(true,...
    method assoc (line 697) | default Associative assoc(Object idx, Object o) {
    method cons (line 700) | default IPersistentVector cons(Object o) {
    method empty (line 703) | default IPersistentVector empty() {
    method indexStream (line 708) | default LongStream indexStream(boolean parallel) {
    method objStream (line 713) | default Stream objStream(boolean parallel) {
    method doubleStream (line 717) | default DoubleStream doubleStream(boolean parallel) {
    method longStream (line 721) | default LongStream longStream(boolean parallel) {

FILE: java/ham_fisted/ISeqDef.java
  type ISeqDef (line 23) | public interface ISeqDef extends ISeq, Sequential, List, IHashEq {
    method empty (line 25) | default IPersistentCollection empty(){
    method equiv (line 29) | default boolean equiv(Object obj){
    method seqEquals (line 45) | default boolean seqEquals(Object obj){
    method calcHashCode (line 56) | default int calcHashCode(){
    method calcHasheq (line 64) | default int calcHasheq(){
    method count (line 68) | default int count(){
    method seq (line 76) | default ISeq seq(){
    method cons (line 80) | default ISeq cons(Object o){
    method more (line 84) | default ISeq more(){
    method toArrayList (line 91) | @SuppressWarnings("unchecked")
    method toArray (line 99) | default Object[] toArray(){
    method add (line 103) | default boolean add(Object o){
    method remove (line 107) | default boolean remove(Object o){
    method addAll (line 111) | default boolean addAll(Collection c){
    method clear (line 115) | default void clear(){
    method retainAll (line 119) | default boolean retainAll(Collection c){
    method removeAll (line 123) | default boolean removeAll(Collection c){
    method containsAll (line 127) | default boolean containsAll(Collection c){
    method toArray (line 136) | default Object[] toArray(Object[] a){
    method size (line 140) | default int size(){
    method isEmpty (line 144) | default boolean isEmpty(){
    method contains (line 148) | default boolean contains(Object o){
    method iterator (line 157) | default Iterator iterator(){
    method reify (line 162) | @SuppressWarnings("unchecked")
    method subList (line 167) | default List subList(int fromIndex, int toIndex){
    method set (line 171) | default Object set(int index, Object element){
    method remove (line 175) | default Object remove(int index){
    method indexOf (line 179) | default int indexOf(Object o){
    method lastIndexOf (line 189) | default int lastIndexOf(Object o){
    method listIterator (line 193) | default ListIterator listIterator(){
    method listIterator (line 197) | default ListIterator listIterator(int index){
    method get (line 201) | default Object get(int index){
    method add (line 205) | default void add(int index, Object element){
    method addAll (line 209) | default boolean addAll(int index, Collection c){

FILE: java/ham_fisted/ISet.java
  type ISet (line 16) | public interface ISet extends Set, ITypedReduce, IFnDef, Counted, Seqable {
    method count (line 18) | default int count() { return size(); }
    method addAll (line 19) | @SuppressWarnings("unchecked")
    method forEach (line 26) | @SuppressWarnings("unchecked")
    method retainAll (line 30) | default boolean retainAll(Collection c) {
    method containsAll (line 38) | default boolean containsAll(Collection c) {
    method removeAll (line 44) | default boolean removeAll(Collection c) {
    method seq (line 51) | default ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(iterator()...
    method isEmpty (line 52) | default boolean isEmpty() { return size() == 0; }
    method toArray (line 53) | default Object[] toArray() { return ArrayLists.toArray(this); }
    method toArray (line 54) | default Object[] toArray(Object[] d) {
    method invoke (line 57) | default Object invoke(Object arg) { return contains(arg) ? arg : null; }

FILE: java/ham_fisted/ITypedReduce.java
  type ITypedReduce (line 19) | public interface ITypedReduce<E> extends IReduceInit, IReduce {
    method parallelReduction (line 20) | default Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
    class Reduce1 (line 26) | static class Reduce1 implements IFnDef {
      method Reduce1 (line 29) | public Reduce1(IFn rf) {
      method invoke (line 33) | public Object invoke(Object acc, Object v) {
    method reduce (line 42) | default Object reduce(IFn rfn) {
    method forEach (line 52) | @SuppressWarnings("unchecked")

FILE: java/ham_fisted/ImmutList.java
  class ImmutList (line 38) | public class ImmutList
    method ImmutList (line 50) | ImmutList(int sidx, int eidx, ChunkedList d) {
    method create (line 55) | public static IPersistentVector create(boolean owning, IPersistentMap ...
    method indexCheck (line 60) | final int indexCheck(int idx) {
    method wrapIndexCheck (line 63) | final int wrapIndexCheck(int idx) {
    method getChunkedList (line 66) | public ChunkedListSection getChunkedList() {
    method hashCode (line 69) | public final int hashCode() {
    method hasheq (line 75) | public final int hasheq() { return hashCode(); }
    method equals (line 76) | public final boolean equals(Object other) {
    method toString (line 80) | public final String toString() { return Transformables.sequenceToStrin...
    method equiv (line 81) | public final boolean equiv(Object other) {
    method size (line 85) | public final int size() { return nElems; }
    method count (line 86) | public final int count() { return nElems; }
    method length (line 87) | public final int length() { return nElems; }
    method clear (line 88) | public final void clear() {
    method add (line 91) | public final boolean add(Object e) {
    method add (line 94) | public final void add(int idx, Object e) {
    method addAll (line 97) | public final boolean addAll(Collection e) {
    method addAll (line 100) | public final boolean addAll(int idx, Collection e) {
    method remove (line 103) | public final Object remove(int idx) {
    method remove (line 106) | public final boolean remove(Object o) {
    method removeAll (line 109) | public final boolean removeAll(Collection c) {
    method retainAll (line 112) | public final boolean retainAll(Collection c) {
    method isEmpty (line 115) | public final boolean isEmpty() { return nElems == 0; }
    method set (line 116) | @SuppressWarnings("unchecked")
    method get (line 120) | @SuppressWarnings("unchecked")
    method indexOf (line 124) | public final int indexOf(Object obj) {
    method lastIndexOf (line 127) | public final int lastIndexOf(Object obj) {
    method contains (line 130) | public final boolean contains(Object obj) {
    method containsAll (line 133) | public final boolean containsAll(Collection c) {
    method iterator (line 136) | @SuppressWarnings("unchecked")
    method subList (line 140) | public final IMutList subList(int sidx, int eidx) {
    method toArray (line 144) | public final Object[] toArray() {
    method toArray (line 147) | public final Object[] toArray(Object[] marker) {
    method meta (line 150) | public IPersistentMap meta() { return data.meta(); }
    method withMeta (line 151) | public ImmutList withMeta(IPersistentMap m) {
    method nth (line 155) | public final Object nth(int idx) { return data.getValue(wrapIndexCheck...
    method nth (line 156) | public final Object nth(int idx, Object notFound) {
    method invoke (line 161) | public final Object invoke(Object idx) {
    method invoke (line 164) | public final Object invoke(Object idx, Object notFound) {
    method reduce (line 167) | public final Object reduce(IFn f) {
    method reduce (line 170) | public final Object reduce(IFn f, Object init) {
    method kvreduce (line 173) | public final Object kvreduce(IFn f, Object init) {
    method seq (line 176) | public final ISeq seq() { return data.seq(startidx, startidx+nElems); }
    method rseq (line 177) | public final ISeq rseq() { return data.rseq(startidx, startidx+nElems); }
    method cons (line 178) | public final ImmutList cons(Object obj) {
    method assocN (line 181) | public final ImmutList assocN(int idx, Object obj) {
    method assoc (line 187) | public final ImmutList assoc(Object idx, Object obj) {
    method entryAt (line 190) | public IMapEntry entryAt(Object key) {
    method containsKey (line 193) | public final boolean containsKey(Object key) {
    method empty (line 200) | public final ImmutList empty() {
    method valAt (line 203) | public final Object valAt(Object obj, Object notFound) {
    method valAt (line 211) | public final Object valAt(Object obj) {
    method pop (line 214) | public final ImmutList pop() {
    method peek (line 221) | public final Object peek() {
    method updateValues (line 227) | @SuppressWarnings("unchecked")
    method updateValue (line 243) | @SuppressWarnings("unchecked")
    method asTransient (line 263) | public final ITransientVector asTransient() {

FILE: java/ham_fisted/ImmutSort.java
  type ImmutSort (line 12) | public interface ImmutSort<E> extends List<E> {
    method compare (line 16) | public int compare(Object l, Object r) {
    method immutSortList (line 27) | @SuppressWarnings("unchecked")
    method immutSort (line 38) | default List immutSort() { return immutSort(null); }
    method immutSort (line 39) | default List immutSort(Comparator c) {

FILE: java/ham_fisted/IndexedConsumer.java
  type IndexedConsumer (line 4) | public interface IndexedConsumer {
    method accept (line 5) | public void accept(long index, Object val);

FILE: java/ham_fisted/IndexedDoubleConsumer.java
  type IndexedDoubleConsumer (line 4) | public interface IndexedDoubleConsumer {
    method accept (line 5) | public void accept(long idx, double val);

FILE: java/ham_fisted/IndexedLongConsumer.java
  type IndexedLongConsumer (line 4) | public interface IndexedLongConsumer {
    method accept (line 5) | public void accept(long idx, long val);

FILE: java/ham_fisted/IntegerOps.java
  class IntegerOps (line 7) | public final class IntegerOps {
    method nextPow2 (line 9) | public static final int nextPow2(int value) {
    method mask (line 22) | public static final int mask(int shift, int hash) {
    method bitpos (line 30) | public static final int bitpos(int shift, int hash) {
    method index (line 38) | public static final int index(int bitmap, int bit){
    method incShift (line 45) | public static final int incShift(int shift) {
    method checkedIncShift (line 52) | public static final int checkedIncShift(int shift) {
    method mixhash (line 76) | public static final int mixhash(int h) {
    method mixhash (line 80) | public static final int mixhash(Object key) {
    method highBits (line 87) | public static final int highBits(int sidx, int eidx) {

FILE: java/ham_fisted/Iter.java
  type Iter (line 5) | public interface Iter {
    method get (line 6) | Object get();
    method next (line 7) | Iter next();
    class IteratorIter (line 9) | public static class IteratorIter implements Iter {
      method IteratorIter (line 12) | public IteratorIter(Iterator iter) {
      method get (line 16) | public Object get() { return get; }
      method next (line 17) | public Iter next() {
    class IterIterator (line 26) | public static class IterIterator implements Iterator {
      method IterIterator (line 28) | public IterIterator(Iter iter) {
      method iter (line 31) | public Iter iter() { return iter; }
      method hasNext (line 32) | public boolean hasNext() { return iter != null; }
      method next (line 33) | public Object next() {
    method fromIterator (line 40) | public static Iter fromIterator(Iterator iter) {
    method fromIter (line 44) | public static Iterator fromIter(Iter iter) {
    method fromIterable (line 48) | public static Iter fromIterable(Iterable iable) {
    method prepend (line 51) | public static Iter prepend(Object obj, Iter item) {

FILE: java/ham_fisted/LazyChunkedSeq.java
  class LazyChunkedSeq (line 19) | public class LazyChunkedSeq extends ASeq implements IChunkedSeq {
    method LazyChunkedSeq (line 24) | public LazyChunkedSeq(IFn fn, IChunkedSeq s, Throwable e, IPersistentM...
    method LazyChunkedSeq (line 31) | public LazyChunkedSeq(IFn fn) {
    method withMeta (line 34) | public LazyChunkedSeq withMeta(IPersistentMap m) { return new LazyChun...
    method unlockedUnwrap (line 35) | IChunkedSeq unlockedUnwrap() {
    method lockedUnwrap (line 48) | IChunkedSeq lockedUnwrap() {
    method first (line 61) | public Object first() {
    method next (line 65) | public ISeq next() {
    method more (line 69) | public ISeq more() {
    method chunkedFirst (line 73) | public IChunk chunkedFirst() {
    method chunkedNext (line 77) | public ISeq chunkedNext() {
    method chunkedMore (line 81) | public ISeq chunkedMore() {
    method chunkIteratorSeq (line 86) | public static IChunkedSeq chunkIteratorSeq(Iterator i) {

FILE: java/ham_fisted/LinkedHashMap.java
  class LinkedHashMap (line 17) | public class LinkedHashMap extends HashMap {
    method LinkedHashMap (line 22) | public LinkedHashMap(IPersistentMap meta) {
    method LinkedHashMap (line 25) | public LinkedHashMap() {
    method LinkedHashMap (line 28) | public LinkedHashMap(float loadFactor, int initialCapacity,
    method clone (line 33) | public LinkedHashMap clone() {
    method newNode (line 48) | protected HashNode newNode(Object key, int hc, Object val) {
    method inc (line 51) | protected void inc(HashNode lf) {
    method removeLink (line 61) | protected static void removeLink(LinkedHashNode hn) {
    method dec (line 67) | protected void dec(HashNode lf) {
    method modify (line 77) | protected void modify(HashNode n) {
    class LinkedIter (line 95) | public static class LinkedIter implements Iterator {
      method LinkedIter (line 98) | public LinkedIter(Function<Map.Entry,Object> fn, LinkedHashNode c) {...
      method hasNext (line 99) | public boolean hasNext() { return current != null; }
      method next (line 100) | public Object next() {
    method iterator (line 107) | public Iterator iterator(Function<Map.Entry,Object> fn) {
    method reduce (line 110) | public Object reduce(IFn rfn, Object acc) {
    method kvreduce (line 118) | public Object kvreduce(IFn rfn, Object acc) {
    method union (line 126) | public HashMap union(Map o, BiFunction bfn) {

FILE: java/ham_fisted/LinkedHashNode.java
  class LinkedHashNode (line 4) | public class LinkedHashNode extends HashNode {
    method LinkedHashNode (line 9) | public LinkedHashNode(LinkedHashMap owner, Object _k, int hc, Object _...
    method clone (line 12) | public HashNode clone(HashMap nowner) {
    method setOwner (line 15) | public HashNode setOwner(HashMap nowner) {
    method assoc (line 22) | public final HashNode assoc(HashMap nowner, Object _k, int hash, Objec...
    method dissoc (line 37) | public final HashNode dissoc(HashMap nowner, Object _k) {

FILE: java/ham_fisted/LongAccum.java
  class LongAccum (line 10) | public class LongAccum implements LongConsumer, IDeref, Reducible {
    method LongAccum (line 12) | public LongAccum(long v) { val = v; }
    method LongAccum (line 13) | public LongAccum() { this(0); }
    method accept (line 14) | public void accept(long v) { val += v; }
    method deref (line 15) | public Object deref() { return val; }
    method reduce (line 16) | public LongAccum reduce(Reducible other) {

FILE: java/ham_fisted/LongHashBase.java
  class LongHashBase (line 18) | public class LongHashBase implements IMeta {
    method LongHashBase (line 26) | public LongHashBase(float loadFactor, int initialCapacity,
    method LongHashBase (line 38) | public LongHashBase(LongHashBase other, IPersistentMap m) {
    method size (line 47) | public int size() { return length; }
    method count (line 48) | public int count() { return length; }
    method hash (line 50) | static int hash(long k) {
    method equals (line 53) | static boolean equals(long lhs, long rhs) {
    method inc (line 56) | protected void inc(LongHashNode lf) { ++this.length; }
    method dec (line 57) | protected void dec(LongHashNode lf) { --this.length; }
    method modify (line 58) | protected void modify(LongHashNode lf) {}
    method newNode (line 59) | protected LongHashNode newNode(long key, int hc, Object val) {
    method checkResize (line 63) | Object checkResize(Object rv) {
    method clear (line 116) | public void clear() {
    method meta (line 125) | public IPersistentMap meta() { return meta; }
    class HTIter (line 126) | static class HTIter implements Iterator {
      method HTIter (line 132) | HTIter(LongHashNode[] data, Function<Map.Entry,Object> fn) {
      method advance (line 140) | void advance() {
      method hasNext (line 148) | public boolean hasNext() { return l != null; }
      method next (line 149) | public Object next() {
    class HTSpliterator (line 155) | static class HTSpliterator implements Spliterator, ITypedReduce {
      method HTSpliterator (line 162) | public HTSpliterator(LongHashNode[] d, int len, Function<Map.Entry,O...
      method HTSpliterator (line 170) | public HTSpliterator(LongHashNode[] d, int sidx, int eidx, int es, F...
      method trySplit (line 178) | public HTSpliterator trySplit() {
      method characteristics (line 189) | public int characteristics() { return Spliterator.DISTINCT | Spliter...
      method estimateSize (line 190) | public long estimateSize() { return estimateSize; }
      method getExactSizeIfKnown (line 191) | public long getExactSizeIfKnown() { return estimateSize(); }
      method tryAdvance (line 192) | @SuppressWarnings("unchecked")
      method reduce (line 209) | public Object reduce(IFn rfn, Object acc) {
    method containsNodeKey (line 223) | final boolean containsNodeKey(Object kk) {

FILE: java/ham_fisted/LongHashMap.java
  class LongHashMap (line 30) | public class LongHashMap extends LongHashBase implements IMap, MapSetOps...
    method LongHashMap (line 32) | public LongHashMap(float loadFactor, int initialCapacity,
    method LongHashMap (line 37) | public LongHashMap() {
    method LongHashMap (line 40) | public LongHashMap(IPersistentMap m) {
    method LongHashMap (line 43) | public LongHashMap(LongHashMap other, IPersistentMap m) {
    method shallowClone (line 47) | public LongHashMap shallowClone() {
    method clone (line 50) | public LongHashMap clone() {
    method hashCode (line 61) | public int hashCode() {
    method hasheq (line 64) | public int hasheq() {
    method equals (line 67) | public  boolean equals(Object o) {
    method equiv (line 70) | public boolean equiv(Object o) {
    method size (line 73) | public int size() { return this.length; }
    method isEmpty (line 74) | public boolean isEmpty() { return this.length == 0; }
    method toString (line 75) | public String toString() {
    method put (line 90) | public Object put(Object kk, Object val) {
    method putAll (line 113) | public void putAll(Map other) {
    method getOrDefault (line 136) | public Object getOrDefault(Object kk, Object dv) {
    method get (line 146) | public Object get(Object kk) {
    method entryAt (line 156) | public IMapEntry entryAt(Object kk) {
    method containsKey (line 166) | public boolean containsKey(Object key) {
    method compute (line 169) | @SuppressWarnings("unchecked")
    method computeIfAbsent (line 197) | @SuppressWarnings("unchecked")
    method remove (line 222) | public Object remove(Object kk) {
    method reduce (line 239) | public Object reduce(IFn rfn, Object acc) {
    method kvreduce (line 251) | public Object kvreduce(IFn rfn, Object acc) {
    method parallelReduction (line 263) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
    method replaceAll (line 267) | @SuppressWarnings("unchecked")
    method keySet (line 290) | public Set keySet() {
    method union (line 296) | @SuppressWarnings("unchecked")
    method union (line 323) | @SuppressWarnings("unchecked")
    method intersection (line 327) | @SuppressWarnings("unchecked")
    method intersection (line 346) | public LongHashMap intersection(Map o, BiFunction bfn) {
    method intersection (line 350) | public static LongHashMap intersection(LongHashMap rv, Set o) {
    method intersection (line 365) | public LongHashMap intersection(Set o) {
    method difference (line 370) | @SuppressWarnings("unchecked")
    method difference (line 387) | public LongHashMap difference(Collection o) {
    method updateValues (line 391) | @SuppressWarnings("unchecked")
    method updateValues (line 407) | public LongHashMap updateValues(BiFunction valueMap) {
    method updateValue (line 410) | @SuppressWarnings("unchecked")
    method updateValue (line 424) | public LongHashMap updateValue(Object k, Function fn) {
    method iterator (line 428) | public Iterator iterator(Function<Map.Entry,Object> leafFn) {
    method spliterator (line 431) | public Spliterator spliterator(Function<Map.Entry,Object> leafFn) { re...

FILE: java/ham_fisted/LongHashNode.java
  class LongHashNode (line 8) | public class LongHashNode implements Map.Entry, IMutList, IMapEntry {
    method LongHashNode (line 16) | public LongHashNode(LongHashBase _owner, long _k, int hc, Object _v, L...
    method LongHashNode (line 24) | public LongHashNode(LongHashBase _owner, long _k, int hc, Object _v) {
    method LongHashNode (line 27) | public LongHashNode(LongHashBase _owner, long _k, int hc) {
    method LongHashNode (line 30) | LongHashNode(LongHashBase _owner, LongHashNode prev) {
    method setOwner (line 37) | public LongHashNode setOwner(LongHashBase nowner) {
    method clone (line 42) | public LongHashNode clone(LongHashBase nowner) {
    method key (line 48) | public final Object key() { return k; }
    method val (line 49) | public final Object val() { return v; }
    method getKey (line 50) | public final Object getKey() { return k; }
    method getValue (line 51) | public final Object getValue() { return v; }
    method setValue (line 52) | public Object setValue(Object vv) { Object rv = v; v = vv; return rv; }
    method size (line 53) | public final int size() { return 2; }
    method get (line 54) | public final Object get(int idx) {
    method assoc (line 59) | public LongHashNode assoc(LongHashBase nowner, long _k, int hash, Obje...
    method dissoc (line 72) | public LongHashNode dissoc(LongHashBase nowner, long _k) {

FILE: java/ham_fisted/LongMutList.java
  type LongMutList (line 16) | @SuppressWarnings("unchecked")
    method add (line 18) | default boolean add(Object obj) { addLong(Casts.longCast(obj)); return...
    method add (line 19) | default void add(int idx, int count, Object v) {
    method addLong (line 24) | default void addLong(long v) { throw new RuntimeException("Object " + ...
    method addBoolean (line 25) | default void addBoolean( boolean obj ) { addLong(obj ? 1 : 0); }
    method addDouble (line 26) | default void addDouble(double obj) { addLong(Casts.longCast(obj));}
    method set (line 27) | @SuppressWarnings("unchecked")
    method setBoolean (line 29) | default void setBoolean(int idx, boolean obj) { setLong(idx, obj ? 1 :...
    method setDouble (line 30) | default void setDouble(int idx, double obj) { setLong(idx, Casts.longC...
    method get (line 31) | default Object get(int idx) { return getLong(idx); }
    method getDouble (line 32) | default double getDouble(int idx) { return getLong(idx); }
    method fillRange (line 33) | default void fillRange(long startidx, final long endidx, Object v) {
    class LongSubList (line 42) | static class LongSubList extends IMutList.MutSubList<Object> implement...
      method LongSubList (line 43) | @SuppressWarnings("unchecked")
      method reduce (line 47) | public Object reduce(IFn rfn, Object init) { return LongMutList.supe...
    method subList (line 49) | default IMutList<Object> subList(int ssidx, int seidx) {
    method fillRange (line 53) | default void fillRange(final long startidx, List l) {
    method addRange (line 67) | default void addRange(int startidx, int endidx, Object v) {
    method addAllReducible (line 74) | default boolean addAllReducible(Object obj) {
    method indexComparator (line 85) | default IntComparator indexComparator() {
    method sort (line 93) | default void sort(Comparator<? super Object> c) {
    method shuffle (line 106) | default void shuffle(Random r) {
    method immutShuffle (line 109) | default List immutShuffle(Random r) {
    method reduce (line 115) | default Object reduce(final IFn rfn, Object init) {
    method longReduction (line 118) | default Object longReduction(IFn.OLO rfn, Object init) {
    method spliterator (line 124) | @SuppressWarnings("unchecked")

FILE: java/ham_fisted/MapFn.java
  class MapFn (line 7) | public class MapFn implements IFnDef {
    method create (line 8) | public static IFn create(IFn src, IFn dst) {
    method MapFn (line 67) | private MapFn(IFn sfn, IFn dfn) {
    method invoke (line 72) | public Object invoke() {
    method invoke (line 76) | public Object invoke(Object arg1) {
    method invoke (line 80) | public Object invoke(Object arg1, Object arg2) {
    method invoke (line 84) | public Object invoke(Object arg1, Object arg2, Object arg3) {
    method invoke (line 88) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 92) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 96) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 100) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 105) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 110) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 115) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 120) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 126) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 132) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 139) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 146) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 153) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 160) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 167) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 174) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 181) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method invoke (line 190) | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg...
    method applyTo (line 199) | public Object applyTo(ISeq args) {

FILE: java/ham_fisted/MapForward.java
  class MapForward (line 32) | public class MapForward<K,V>
    method MapForward (line 38) | public MapForward(Map<K,V> ht, IPersistentMap meta) { this.ht = ht; th...
    method clear (line 39) | public void clear() { ht.clear(); }
    method compute (line 40) | public V compute(K key, BiFunction<? super K,? super V,? extends V> re...
    method computeIfPresent (line 43) | public V computeIfPresent(K key, BiFunction<? super K,? super V,? exte...
    method computeIfAbsent (line 46) | public V computeIfAbsent(K key, Function<? super K,? extends V> mappin...
    method containsKey (line 49) | public boolean containsKey(Object key) { return ht.containsKey(key); }
    method containsValue (line 50) | public boolean containsValue(Object v) { return ht.containsValue(v); }
    method entrySet (line 51) | public Set<Map.Entry<K,V>> entrySet() { return ht.entrySet(); }
    method equals (line 52) | public boolean equals(Object o) {
    method equiv (line 55) | public boolean equiv(Object o) { return equals(o); }
    method forEach (line 56) | public void forEach(BiConsumer<? super K,? super V> action) {
    method get (line 59) | public V get(Object k) { return ht.get(k); }
    method getOrDefault (line 60) | public V getOrDefault(Object k, V dv) { return ht.getOrDefault(k, dv); }
    method hashCode (line 61) | public int hashCode() { return CljHash.mapHashcode(ht); }
    method hasheq (line 62) | public int hasheq() { return hashCode(); }
    method isEmpty (line 63) | public boolean isEmpty() { return ht.isEmpty(); }
    method keySet (line 64) | public Set<K> keySet() { return ht.keySet(); }
    method merge (line 65) | public V merge(K key, V value, BiFunction<? super V,? super V,? extend...
    method put (line 68) | public V put(K key, V value) { return ht.put(key, value); }
    method putAll (line 69) | public void putAll(Map<? extends K,? extends V> m) { ht.putAll(m); }
    method putIfAbsent (line 70) | public V putIfAbsent(K key, V value) { return ht.putIfAbsent(key, valu...
    method remove (line 71) | public V remove(Object k) { return ht.remove(k); }
    method remove (line 72) | public boolean remove(Object key, Object value) { return ht.remove(key...
    method replace (line 73) | public V replace(K key, V value) { return ht.replace(key, value); }
    method replace (line 74) | public boolean replace(K key, V oldValue, V newValue) {
    method replaceAll (line 77) | public void replaceAll(BiFunction<? super K,? super V,? extends V> fun...
    method size (line 80) | public int size() { return ht.size(); }
    method count (line 81) | public int count() { return ht.size(); }
    method values (line 82) | public Collection<V> values() { return ht.values(); }
    method iterator (line 83) | public Iterator iterator() {
    method keyIterator (line 86) | public Iterator keyIterator() { return keySet().iterator(); }
    method valIterator (line 87) | public Iterator valIterator() { return values().iterator(); }
    method reduce (line 88) | public Object reduce(IFn rfn, Object acc) {
    method entryAt (line 91) | @SuppressWarnings("unchecked")
    method valAt (line 95) | public Object valAt(Object key) {
    method valAt (line 98) | @SuppressWarnings("unchecked")
    method invoke (line 102) | public final Object invoke(Object arg1) {
    method invoke (line 105) | @SuppressWarnings("unchecked")
    method seq (line 109) | public ISeq seq() {
    method meta (line 112) | public IPersistentMap meta() { return meta; }
    method withMeta (line 113) | public MapForward<K,V> withMeta(IPersistentMap m) { return new MapForw...
    method kvreduce (line 114) | @SuppressWarnings("unchecked")

FILE: java/ham_fisted/MapSetOps.java
  type MapSetOps (line 10) | public interface MapSetOps {
    method union (line 11) | Map union(Map rhs, BiFunction bfn);
    method intersection (line 13) | Map intersection(Map rhs, BiFunction bfn);
    method intersection (line 15) | Map intersection(Set rhs);
    method difference (line 16) | default Map difference(Map rhs) { return difference(rhs.keySet()); }
    method difference (line 17) | Map difference(Collection rhs);

FILE: java/ham_fisted/MergeIterator.java
  class MergeIterator (line 11) | public class MergeIterator implements Iterator {
    class CurrentIterator (line 12) | public static class CurrentIterator implements Iterator {
      method CurrentIterator (line 16) | public CurrentIterator(Iterator iter) {
      method CurrentIterator (line 20) | public CurrentIterator(Iterator iter, Object cur) {
      method hasNext (line 24) | public boolean hasNext() { return iter.hasNext(); }
      method next (line 25) | public Object next() {
      method current (line 28) | public Object current() { return current; }
      method hasCurrent (line 29) | public boolean hasCurrent() { return current != invalid; }
      method create (line 30) | public static CurrentIterator create(Iterator iter) {
    method leastIndex (line 41) | @SuppressWarnings("unchecked")
    method MergeIterator (line 57) | public MergeIterator(CurrentIterator[] iters, Comparator cmp, Predicat...
    method hasNext (line 63) | public boolean hasNext() {
    method next (line 66) | @SuppressWarnings("unchecked")
    method hasNext (line 92) | public boolean hasNext() { return false; }
    method next (line 93) | public Object next() { throw new java.util.NoSuchElementException(); }
    class TwoWayMergeIterator (line 95) | public static class TwoWayMergeIterator implements Iterator {
      method TwoWayMergeIterator (line 101) | @SuppressWarnings("unchecked")
      method hasNext (line 109) | public boolean hasNext() {
      method next (line 112) | @SuppressWarnings("unchecked")
      method create (line 132) | public static Iterator create(Iterator lhs, Iterator rhs, Comparator...
    class PriorityQueueIterator (line 138) | public static class PriorityQueueIterator implements Iterator {
      method PriorityQueueIterator (line 141) | public PriorityQueueIterator(PriorityQueue pq, Predicate p) {
      method hasNext (line 145) | public boolean hasNext() {
      method next (line 148) | @SuppressWarnings("unchecked")
      method create (line 163) | @SuppressWarnings("unchecked")
      method create (line 177) | public static Iterator create(Iterable<Iterator> srcIters, Comparato...
    method createMergeIterator (line 181) | @SuppressWarnings("unchecked")
    method test (line 204) | public boolean test(Object o){ return true; }
    method createMergeIterator (line 205) | public static Iterator createMergeIterator(Iterable<Iterator> srcIters...

FILE: java/ham_fisted/MethodImplCache.java
  class MethodImplCache (line 23) | public final class MethodImplCache {
    method MethodImplCache (line 43) | public MethodImplCache(Keyword methodk, Keyword ns_methodk, Class ifac...
    method extend (line 51) | public void extend(Class c, Object fn) {
    method registeredClasses (line 68) | public Set registeredClasses() { return extensions.keySet(); }
    method recurCheckInterface (line 70) | @SuppressWarnings("unchecked")
    method findFnFor (line 92) | @SuppressWarnings("unchecked")

FILE: java/ham_fisted/MutList.java
  class MutList (line 35) | public class MutList<E>
    method MutList (line 39) | public MutList() { data = new ChunkedList(); }
    method MutList (line 40) | public MutList(int capacity) { data = new ChunkedList(capacity); }
    method MutList (line 41) | public MutList(ChunkedList other) {
    method MutList (line 45) | public MutList(MutList<E> other) {
    method create (line 48) | @SafeVarargs
    method getChunkedList (line 52) | public final ChunkedListSection getChunkedList() {
    method clone (line 55) | public final MutList<E> clone() { return new MutList<E>(this); }
    method cloneList (line 56) | public final MutList<E> cloneList() {
    method add (line 59) | public final boolean add(E v) { data.add(v); return true; }
    method add (line 60) | public final void add(int idx, E v) { data.add(v,idx); }
    method addAll (line 61) | public final boolean addAll(Collection<? extends E> c) {
    method addAllReducible (line 65) | @SuppressWarnings("unchecked")
    method addAll (line 135) | public final boolean addAll(int idx, Collection<? extends E> c) {
    method clear (line 155) | public final void clear() { data.clear(); }
    method contains (line 157) | public final boolean contains(Object v) {
    method containsAll (line 161) | public final boolean containsAll(Collection<?> c) {
    method indexCheck (line 165) | final int indexCheck(int idx) {
    method indexCheck (line 169) | final int indexCheck(long idx) {
    method wrapIndexCheck (line 173) | final int wrapIndexCheck(int idx) {
    method set (line 177) | @SuppressWarnings("unchecked")
    method get (line 182) | @SuppressWarnings("unchecked")
    method indexOf (line 187) | public final int indexOf(Object o) {
    method isEmpty (line 191) | public final boolean isEmpty() { return data.nElems == 0; }
    method iterator (line 193) | @SuppressWarnings("unchecked")
    class SubMutList (line 196) | public static class SubMutList<E> implements IMutList<E>, ChunkedListO...
      method SubMutList (line 202) | SubMutList(int sidx, int eidx, ChunkedList d) {
      method getChunkedList (line 208) | public final ChunkedListSection getChunkedList() {
      method clone (line 212) | public final MutList<E> clone() {
      method cloneList (line 216) | public final MutList<E> cloneList() {
      method indexCheck (line 220) | final int indexCheck(int idx) {
      method wrapIndexCheck (line 224) | final int wrapIndexCheck(int idx) {
      method size (line 228) | public final int size() { return nElems; }
      method isEmpty (line 229) | public final boolean isEmpty() { return nElems == 0; }
      method set (line 230) | @SuppressWarnings("unchecked")
      method get (line 234) | @SuppressWarnings("unchecked")
      method indexOf (line 238) | public final int indexOf(Object obj) {
      method lastIndexOf (line 241) | public final int lastIndexOf(Object obj) {
      method contains (line 244) | public final boolean contains(Object obj) {
      method containsAll (line 247) | public final boolean containsAll(Collection<?> c) {
      method iterator (line 250) | @SuppressWarnings("unchecked")
      method listIterator (line 254) | public final ListIterator<E> listIterator(int idx) {
      method listIterator (line 257) | public final ListIterator<E> listIterator() {
      method subList (line 260) | public final IMutList<E> subList(int ssidx, int seidx) {
      method toArray (line 264) | public final Object[] toArray() {
      method toArray (line 267) | @SuppressWarnings("unchecked")
      method nth (line 271) | public final Object nth(int idx) { return data.getValue(wrapIndexChe...
      method nth (line 272) | public final Object nth(int idx, Object notFound) {
      method invoke (line 278) | public final Object invoke(Object idx) {
      method invoke (line 281) | public final Object invoke(Object idx, Object notFound) {
      method count (line 284) | public final int count() { return nElems; }
      method reduce (line 286) | public final Object reduce(IFn f) {
      method reduce (line 290) | public final Object reduce(IFn f, Object init) {
      method kvreduce (line 294) | public final Object kvreduce(IFn f, Object init) {
      method fillRange (line 297) | public void fillRange(long sidx, long eidx, Object v) {
      method fillRange (line 303) | public void fillRange(long sidx, List v) {
      method hashCode (line 310) | public final int hashCode() {
      method hasheq (line 313) | public final int hasheq() {
      method toString (line 316) | public final String toString() {
      method equals (line 319) | public final boolean equals(Object other) {
      method equiv (line 322) | public final boolean equiv(Object other) {
      method seq (line 325) | public final ISeq seq() { return data.seq(startidx, startidx+nElems); }
      method rseq (line 326) | public final ISeq rseq() { return data.rseq(startidx, startidx+nElem...
      method meta (line 327) | public IPersistentMap meta() { return data.meta(); }
      method withMeta (line 328) | public SubMutList<E> withMeta(IPersistentMap m) {
    method subList (line 333) | public final IMutList<E> subList(int startidx, int endidx) {
    method listIterator (line 338) | public final ListIterator<E> listIterator(int idx) {
    method listIterator (line 341) | public final ListIterator<E> listIterator() { return listIterator(0); }
    method lastIndexOf (line 343) | public final int lastIndexOf(Object obj) {
    method remove (line 347) | @SuppressWarnings("unchecked")
    method fillRange (line 354) | public void fillRange(int startidx, int endidx, Object v) {
    method fillRange (line 361) | public void fillRange(int startidx, List v) {
    method addRange (line 369) | public void addRange(int startidx, int endidx, Object v) {
    method removeRange (line 374) | public void removeRange(int startidx, int endidx) {
    method remove (line 385) | public final boolean remove(Object obj) {
    method retainAll (line 392) | public final boolean retainAll(Collection c) {
    method removeAll (line 396) | public final boolean removeAll(Collection c) {
    method toArray (line 400) | @SuppressWarnings("unchecked")
    method toArray (line 405) | public final Object[] toArray() {
    method size (line 409) | public final int size() { return data.nElems; }
    method capacity (line 410) | public final int capacity() { return data.capacity; }
    method nth (line 412) | public final Object nth(int idx) { return data.getValue(wrapIndexCheck...
    method nth (line 413) | public final Object nth(int idx, Object notFound) {
    method invoke (line 419) | public final Object invoke(Object idx) {
    method invoke (line 422) | public final Object invoke(Object idx, Object notFound) {
    method count (line 425) | public final int count() { return data.size(); }
    method reduce (line 427) | public final Object reduce(IFn f) {
    method reduce (line 431) | public final Object reduce(IFn f, Object init) {
    method kvreduce (line 435) | public final Object kvreduce(IFn f, Object init) {
    method seq (line 439) | public final ISeq seq() { return data.seq(0, data.nElems); }
    method rseq (line 440) | public final ISeq rseq() { return data.rseq(0, data.nElems); }
    method hashCode (line 442) | public final int hashCode() {
    method hasheq (line 445) | public final int hasheq() {
    method equals (line 448) | public final boolean equals(Object other) {
    method equiv (line 453) | public final boolean equiv(Object other) {
    method toString (line 456) | public final String toString() {
    method meta (line 459) | public IPersistentMap meta() { return data.meta(); }
    method withMeta (line 460) | public MutList<E> withMeta(IPersistentMap m) {
    method assocN (line 463) | @SuppressWarnings("unchecked")
    method pop (line 469) | public final MutList<E> pop() {
    method assoc (line 475) | public final MutList<E> assoc(Object i, Object obj) {
    method conj (line 480) | @SuppressWarnings("unchecked")
    method valAt (line 485) | public final Object valAt(Object key) {
    method valAt (line 488) | public final Object valAt(Object key, Object notFound) {
    method persistent (line 496) | public ImmutList persistent() { return new ImmutList(0, data.nElems, d...
    method updateValues (line 497) | public ImmutList updateValues(BiFunction valueMap) {
    method updateValue (line 500) | public ImmutList updateValue(Object key, Function valueMap) {

FILE: java/ham_fisted/MutTreeList.java
  class MutTreeList (line 10) | public class MutTreeList extends TreeListBase implements ITransientVector {
    method nTail (line 15) | public int nTail() { return nTail; }
    method validTail (line 16) | public Object[] validTail() {
    method MutTreeList (line 19) | public MutTreeList(Object root, Object[] tail, IPersistentMap meta, in...
    method MutTreeList (line 23) | public MutTreeList() {
    method MutTreeList (line 28) | public MutTreeList(TreeListBase other, IPersistentMap meta) {
    method consTail (line 34) | void consTail(Object[] tail) {
    method add (line 43) | public boolean add(Object obj) {
    method set (line 55) | public Object set(int idx, Object obj) {
    method setObject (line 71) | public void setObject(int idx, Object obj) {
    method assocN (line 83) | public MutTreeList assocN(int i, Object val) {
    method pop (line 88) | public MutTreeList pop() {
    method assoc (line 106) | public MutTreeList assoc(Object key, Object val) {
    method conj (line 109) | public MutTreeList conj(Object val) { add(val); return this; }
    method persistent (line 110) | public TreeList persistent() {
    method immut (line 116) | public IPersistentVector immut() { return persistent(); }
    method create (line 117) | public static MutTreeList create(boolean owning, IPersistentMap meta, ...

FILE: java/ham_fisted/MutableMap.java
  type MutableMap (line 4) | public interface MutableMap {}

FILE: java/ham_fisted/ObjArray.java
  class ObjArray (line 8) | public class ObjArray {
    method create (line 9) | public static final Object[] create() { return new Object[0]; }
    method create (line 10) | public static final Object[] create(Object a) { return new Object[] {a...
    method create (line 11) | public static final Object[] create(Object a, Object b) { return new O...
    method create (line 12) | public static final Object[] create(Object a, Object b, Object c) {
    method create (line 15) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 18) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 21) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method createv (line 25) | public static final Object[] createv(Object a, Object b, Object c, Obj...
    method create (line 35) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 39) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method createv (line 43) | public static final Object[] createv(Object a, Object b, Object c, Obj...
    method create (line 55) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 60) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 65) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 70) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 75) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 81) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 87) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method create (line 93) | public static final Object[] create(Object a, Object b, Object c, Obje...
    method createv (line 99) | public static final Object[] createv(Object a, Object b, Object c, Obj...
    method iterFill (line 118) | public static Object[] iterFill(Object[] data, int idx, Iterator iter) {

FILE: java/ham_fisted/ParallelOptions.java
  class ParallelOptions (line 8) | public class ParallelOptions {
    type CatParallelism (line 21) | public enum CatParallelism {
    method ParallelOptions (line 29) | public ParallelOptions(long _minN, int batchSize, boolean _ordered,
    method ParallelOptions (line 43) | public ParallelOptions(long minN, int batchSize, boolean ordered) {
    method ParallelOptions (line 48) | public ParallelOptions() {
    method minN (line 51) | public ParallelOptions minN(long newMinN) {

FILE: java/ham_fisted/PartitionByInner.java
  class PartitionByInner (line 20) | public class PartitionByInner implements ITypedReduce, Iterator, Seqable...
    method PartitionByInner (line 29) | public PartitionByInner(Iterator i, IFn f, Object v, BiPredicate pred) {
    method advance (line 40) | Object advance() {
    method reduce (line 55) | @SuppressWarnings("unchecked")
    method hasNext (line 82) | @SuppressWarnings("unchecked")
    method next (line 86) | public Object next() {
    method seq (line 90) | public ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(this); }
    method deref (line 91) | public Object deref() {
    method meta (line 96) | public IPersistentMap meta() {

FILE: java/ham_fisted/PersistentHashMap.java
  class PersistentHashMap (line 15) | public class PersistentHashMap
    method PersistentHashMap (line 21) | PersistentHashMap(HashMap data) {
    method PersistentHashMap (line 24) | public PersistentHashMap(HashMap data, boolean marker) {
    method PersistentHashMap (line 27) | PersistentHashMap(HashMap data, IPersistentMap m) {
    method count (line 31) | public int count() { return length; }
    method hasheq (line 32) | public int hasheq() {
    method assoc (line 37) | public PersistentHashMap assoc(Object key, Object val) {
    method without (line 58) | public IPersistentMap without(Object key) {
    method asTransient (line 69) | public ITransientMap asTransient() {
    method withMeta (line 73) | public PersistentHashMap withMeta(IPersistentMap m) {
    method empty (line 76) | public PersistentHashMap empty() { return EMPTY; }
    method union (line 77) | public PersistentHashMap union(Map o, BiFunction bfn) {
    method intersection (line 80) | public PersistentHashMap intersection(Map o, BiFunction bfn) {
    method intersection (line 83) | public PersistentHashMap intersection(Set o) {
    method difference (line 86) | public PersistentHashMap difference(Collection c) {
    method updateValues (line 89) | public PersistentHashMap updateValues(BiFunction valueMap) {
    method updateValue (line 92) | public PersistentHashMap updateValue(Object k, Function fn) {

FILE: java/ham_fisted/PersistentHashSet.java
  class PersistentHashSet (line 11) | public class PersistentHashSet extends ROHashSet implements IAPersistent...
    method PersistentHashSet (line 13) | public PersistentHashSet() { super(); }
    method PersistentHashSet (line 14) | public PersistentHashSet(HashBase hb) {
    method PersistentHashSet (line 17) | public PersistentHashSet(HashBase hb, IPersistentMap meta) {
    method withMeta (line 20) | public PersistentHashSet withMeta(IPersistentMap m) {
    method asTransient (line 23) | public ITransientSet asTransient() {
    method empty (line 26) | public PersistentHashSet empty() { return EMPTY; }
    method union (line 27) | public PersistentHashSet union(Collection rhs) {
    method intersection (line 30) | public PersistentHashSet intersection(Set rhs) {
    method difference (line 33) | public PersistentHashSet difference(Set rhs) {

FILE: java/ham_fisted/PersistentLongHashMap.java
  class PersistentLongHashMap (line 14) | public class PersistentLongHashMap
    method PersistentLongHashMap (line 20) | public PersistentLongHashMap(LongHashMap data) {
    method PersistentLongHashMap (line 23) | public PersistentLongHashMap(LongHashMap data, IPersistentMap m) {
    method count (line 26) | public int count() { return length; }
    method hasheq (line 27) | public int hasheq() {
    method asTransient (line 32) | public ITransientMap asTransient() {
    method withMeta (line 36) | public PersistentLongHashMap withMeta(IPersistentMap m) {
    method empty (line 39) | public PersistentLongHashMap empty() { return EMPTY; }
    method union (line 40) | public PersistentLongHashMap union(Map o, BiFunction bfn) {
    method intersection (line 43) | public PersistentLongHashMap intersection(Map o, BiFunction bfn) {
    method intersection (line 46) | public PersistentLongHashMap intersection(Set o) {
    method difference (line 49) | public PersistentLongHashMap difference(Collection c) {
    method updateValues (line 52) | public PersistentLongHashMap updateValues(BiFunction valueMap) {
    method updateValue (line 55) | public PersistentLongHashMap updateValue(Object k, Function fn) {

FILE: java/ham_fisted/PersistentVector.java
  class PersistentVector (line 6) | public class PersistentVector {

FILE: java/ham_fisted/ROHashMap.java
  class ROHashMap (line 11) | public class ROHashMap extends HashMap {
    method ROHashMap (line 12) | ROHashMap(float loadFactor, int initialCapacity,
    method ROHashMap (line 17) | ROHashMap(HashMap other, IPersistentMap m) {
    method remove (line 20) | public Object remove(Object k) {
    method put (line 23) | public Object put(Object key, Object value) {
    method putAll (line 26) | public void putAll(Map m) {
    method clear (line 29) | public void clear() {
    method compute (line 32) | public Object compute(Object key, BiFunction bfn) {
    method computeIfAbsent (line 35) | public Object computeIfAbsent(Object key, Function mappingFunction) {
    method computeIfPresent (line 38) | public Object computeIfPresent(Object key, BiFunction remappingFunctio...
    method merge (line 41) | public Object merge(Object key, Object value, BiFunction remappingFunc...
    method replaceAll (line 44) | public void replaceAll(BiFunction function) {

FILE: java/ham_fisted/ROHashSet.java
  class ROHashSet (line 8) | public class ROHashSet extends HashSet {
    method ROHashSet (line 9) | public ROHashSet() {
    method ROHashSet (line 12) | public ROHashSet(HashBase hs) {
    method ROHashSet (line 15) | public ROHashSet(HashBase hs, IPersistentMap meta) {
    method add (line 18) | public boolean add(Object o) {
    method addAll (line 21) | public boolean addAll(Collection c) {
    method remove (line 24) | public boolean remove(Object o) {

FILE: java/ham_fisted/ROLongHashMap.java
  class ROLongHashMap (line 11) | public class ROLongHashMap extends LongHashMap {
    method ROLongHashMap (line 12) | ROLongHashMap(float loadFactor, int initialCapacity,
    method ROLongHashMap (line 17) | ROLongHashMap(LongHashMap other, IPersistentMap m) {
    method remove (line 20) | public Object remove(Object k) {
    method put (line 23) | public Object put(Object key, Object value) {
    method putAll (line 26) | public void putAll(Map m) {
    method clear (line 29) | public void clear() {
    method compute (line 32) | public Object compute(Object key, BiFunction bfn) {
    method computeIfAbsent (line 35) | public Object computeIfAbsent(Object key, Function mappingFunction) {
    method computeIfPresent (line 38) | public Object computeIfPresent(Object key, BiFunction remappingFunctio...
    method merge (line 41) | public Object merge(Object key, Object value, BiFunction remappingFunc...
    method replaceAll (line 44) | public void replaceAll(BiFunction function) {

FILE: java/ham_fisted/RandomAccessSpliterator.java
  class RandomAccessSpliterator (line 11) | public class RandomAccessSpliterator<E> implements Spliterator<E> {
    method RandomAccessSpliterator (line 18) | RandomAccessSpliterator(List<E> list, int sidx, int eidx) {
    method RandomAccessSpliterator (line 27) | RandomAccessSpliterator(List<E> list) {
    method construct (line 31) | protected Spliterator<E> construct(List<E> list, int split, int eidx) {
    method doSplit (line 35) | protected Spliterator<E> doSplit() {
    method trySplit (line 46) | public Spliterator<E> trySplit() {
    method estimateSize (line 50) | public long estimateSize() { return eidx - sidx; }
    method tryAdvance (line 52) | public boolean tryAdvance(Consumer<? super E> action) {
    method forEachRemaining (line 63) | public void forEachRemaining(Consumer<? super E> c) {
    method characteristics (line 91) | public int characteristics() {
    class LongSpliterator (line 94) | public static class LongSpliterator extends RandomAccessSpliterator<Lo...
      method LongSpliterator (line 95) | @SuppressWarnings("unchecked")
      method construct (line 99) | protected Spliterator<Long> construct(List list, int sidx, int eidx) {
      method trySplit (line 102) | public Spliterator.OfLong trySplit() {
      method tryAdvance (line 105) | public boolean tryAdvance(LongConsumer action) {
      method forEachRemaining (line 115) | public void forEachRemaining(LongConsumer dc) {
    class DoubleSpliterator (line 124) | public static class DoubleSpliterator extends RandomAccessSpliterator<...
      method DoubleSpliterator (line 125) | @SuppressWarnings("unchecked")
      method construct (line 129) | protected Spliterator<Double> construct(List list, int sidx, int eid...
      method trySplit (line 132) | public Spliterator.OfDouble trySplit() {
      method tryAdvance (line 135) | public boolean tryAdvance(DoubleConsumer action) {
      method forEachRemaining (line 145) | public void forEachRemaining(DoubleConsumer dc) {

FILE: java/ham_fisted/RangeList.java
  type RangeList (line 7) | public interface RangeList {
    method fillRange (line 8) | public void fillRange(long startidx, long endidx, Object v);
    method fillRange (line 9) | default void fillRange(long startidx, List v) {
    method fillRangeReducible (line 12) | public void fillRangeReducible(long startidx, Object v);
    method removeRange (line 13) | public void removeRange(long startidx, long endidx);

FILE: java/ham_fisted/Ranges.java
  class Ranges (line 18) | public class Ranges {
    class LongRange (line 19) | public static class LongRange implements LongMutList, TypedList {
      method LongRange (line 26) | public LongRange(long s, long e, long _step, IPersistentMap m) {
      method cloneList (line 37) | public IMutList cloneList() { return this; }
      method equals (line 38) | public boolean equals(Object other) {
      method hashCode (line 41) | public int hashCode() { return hasheq(); }
      method hasheq (line 42) | public int hasheq() {
      method toString (line 48) | public String toString() { return Transformables.sequenceToString(th...
      method containedType (line 49) | public Class containedType() { return Long.TYPE; }
      method size (line 50) | public int size() { return RT.intCast(nElems); }
      method lgetLong (line 51) | public long lgetLong(long idx) {
      method getLong (line 58) | public long getLong(int idx) {
      method toIntArray (line 61) | public int[] toIntArray() {
      method toLongArray (line 64) | public long[] toLongArray() {
      method toDoubleArray (line 67) | public double[] toDoubleArray() {
      method toArray (line 70) | public Object[] toArray() {
      method subList (line 80) | public LongMutList subList(long sidx, long eidx) {
      method seq (line 84) | public ISeq seq() { return inplaceSublistSeq(); }
      method subList (line 85) | public LongMutList subList(int sidx, int eidx) {
      method reduce (line 88) | public Object reduce(final IFn fn, Object init) {
      method parallelReduction (line 111) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
      method lnth (line 119) | public Object lnth(long idx) {
      method lnth (line 125) | public Object lnth(long idx, Object notFound) {
      method invoke (line 131) | public Object invoke(Object arg) {
      method invoke (line 134) | public Object invoke(Object arg, Object defVal) {
      method meta (line 141) | public IPersistentMap meta() { return meta; }
      method withMeta (line 142) | public LongRange withMeta(IPersistentMap m) {
    class DoubleRange (line 147) | public static class DoubleRange implements DoubleMutList, TypedList {
      method DoubleRange (line 154) | public DoubleRange(double s, double e, double _step, IPersistentMap ...
      method cloneList (line 166) | public IMutList cloneList() { return this; }
      method equals (line 167) | public boolean equals(Object other) {
      method hashCode (line 170) | public int hashCode() { return hasheq(); }
      method hasheq (line 171) | public int hasheq() {
      method toString (line 177) | public String toString() { return Transformables.sequenceToString(th...
      method containedType (line 178) | public Class containedType() { return Double.TYPE; }
      method size (line 179) | public int size() { return RT.intCast(nElems); }
      method lgetDouble (line 180) | public double lgetDouble(long idx) {
      method seq (line 189) | public ISeq seq() { return inplaceSublistSeq(); }
      method getDouble (line 190) | public double getDouble(int idx) { return lgetDouble(idx); }
      method toIntArray (line 191) | public int[] toIntArray() {
      method toLongArray (line 197) | public long[] toLongArray() {
      method toDoubleArray (line 203) | public double[] toDoubleArray() {
      method subList (line 206) | public DoubleMutList subList(long sidx, long eidx) {
      method subList (line 210) | public DoubleMutList subList(int sidx, int eidx) {
      method reduce (line 213) | public Object reduce(final IFn fn, Object init) {
      method doubleReduction (line 221) | public Object doubleReduction(IFn.ODO op, Object init) {
      method parallelReduction (line 229) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
      method lnth (line 241) | public Object lnth(long idx) {
      method lnth (line 247) | public Object lnth(long idx, Object notFound) {
      method invoke (line 253) | public Object invoke(Object arg) {
      method invoke (line 256) | public Object invoke(Object arg, Object defVal) {
      method meta (line 263) | public IPersistentMap meta() { return meta; }
      method withMeta (line 264) | public DoubleRange withMeta(IPersistentMap m) {

FILE: java/ham_fisted/Reducible.java
  type Reducible (line 7) | public interface Reducible
    method reduceIter (line 9) | default Reducible reduceIter(Iterator<Reducible> rest) {
    method reduce (line 15) | Reducible reduce(Reducible rhs);

FILE: java/ham_fisted/Reductions.java
  class Reductions (line 29) | public class Reductions {
    method invoke (line 32) | public Object invoke(Object target, Object ww) {
    method unreduce (line 42) | public static Object unreduce(Object obj) {
    type DoubleAccum (line 46) | public interface DoubleAccum extends IFnDef.ODO {}
    type LongAccum (line 48) | public interface LongAccum extends IFnDef.OLO {}
    method toIterable (line 50) | public static Iterable toIterable(Object obj) {
    method iterReduce (line 59) | public static Object iterReduce(Object obj, IFn fn) {
    method iterReduce (line 70) | public static Object iterReduce(Object obj, Object init, IFn fn) {
    method reduceReducibles (line 80) | public static Reducible reduceReducibles(Iterable<Reducible> data) {
    method invoke (line 87) | public Object invoke() {
    method serialReduction (line 92) | public static Object serialReduction(IFn rfn, Object init, Object coll) {
    method serialReduction (line 100) | @SuppressWarnings("unchecked")
    method iterableMerge (line 111) | public static Object iterableMerge(ParallelOptions options, IFn mergeFn,
    method parallelIndexGroupReduce (line 123) | public static Object parallelIndexGroupReduce(IFn groupFn, long nElems...
    method parallelRandAccessReduction (line 129) | public static Object parallelRandAccessReduction(IFn initValFn, IFn rf...
    class ReduceConsumer (line 139) | public static class ReduceConsumer implements Consumer, IDeref {
      class DoubleReduceConsumer (line 143) | public static class DoubleReduceConsumer extends ReduceConsumer impl...
        method DoubleReduceConsumer (line 145) | public DoubleReduceConsumer(Object in, IFn _rfn) {
        method accept (line 149) | public void accept(Object obj) { accept(Casts.doubleCast(obj)); }
        method accept (line 150) | public void accept(double v) {
      class LongReduceConsumer (line 156) | public static class LongReduceConsumer extends ReduceConsumer implem...
        method LongReduceConsumer (line 158) | public LongReduceConsumer(Object in, IFn _rfn) {
        method accept (line 162) | public void accept(Object obj) { accept(Casts.longCast(obj)); }
        method accept (line 163) | public void accept(long v) {
      method ReduceConsumer (line 169) | public ReduceConsumer(Object in, IFn _rfn) {
      method accept (line 173) | public void accept(Object obj) {
      method isReduced (line 177) | public boolean isReduced() {
      method deref (line 180) | public Object deref() { return init; }
      method create (line 182) | public static ReduceConsumer create(Object init, IFn rfn) {
    method parallelCollectionReduction (line 193) | public static Object parallelCollectionReduction(IFn initValFn, IFn rf...
    method invoke (line 202) | public Object invoke() {
    method parallelReduction (line 207) | public static Object parallelReduction(IFn initValFn, IFn rfn, IFn mer...
    method serialParallelReduction (line 223) | public static Object serialParallelReduction(IFn initValFn, IFn rfn,
    class IndexedDoubleAccum (line 232) | public static class IndexedDoubleAccum implements IFnDef.ODO {
      method IndexedDoubleAccum (line 235) | public IndexedDoubleAccum(long sidx, IFn.OLDO rfn) {
      method IndexedDoubleAccum (line 239) | public IndexedDoubleAccum(IFn.OLDO rfn) {
      method invokePrim (line 242) | public Object invokePrim(Object acc, double v) {
    class IndexedLongAccum (line 246) | public static class IndexedLongAccum implements IFnDef.OLO {
      method IndexedLongAccum (line 249) | public IndexedLongAccum(long sidx, IFn.OLLO rfn) {
      method IndexedLongAccum (line 253) | public IndexedLongAccum(IFn.OLLO rfn) {
      method invokePrim (line 256) | public Object invokePrim(Object acc, long v) {
    class IndexedAccum (line 260) | public static class IndexedAccum implements IFnDef {
      method IndexedAccum (line 263) | public IndexedAccum(long sidx, IFn.OLOO rfn) {
      method IndexedAccum (line 267) | public IndexedAccum(IFn.OLOO rfn) {
      method invoke (line 270) | public Object invoke(Object acc, Object v) {
    class LongCompose (line 274) | static class LongCompose implements IFnDef.OLO {
      method LongCompose (line 277) | public LongCompose(int nVals, Object[] rfns) {
      method invokePrim (line 284) | public Object invokePrim(Object acc, long val) {
    method longCompose (line 294) | public static IFn longCompose(final int nVals, final Object[] rfns) {
    class DoubleCompose (line 298) | static class DoubleCompose implements IFnDef.ODO {
      method DoubleCompose (line 301) | public DoubleCompose(int nVals, Object[] rfns) {
      method invokePrim (line 308) | public Object invokePrim(Object acc, double val) {
    method doubleCompose (line 318) | public static IFn doubleCompose(final int nVals, final Object[] rfns) {
    class ObjCompose (line 322) | static class ObjCompose implements IFnDef {
      method ObjCompose (line 325) | public ObjCompose(int nVals, Object[] rfns) {
      method invoke (line 332) | public Object invoke(Object acc, Object val) {
    method objCompose (line 342) | public static IFn objCompose(final int nVals, final Object[] rfns) {
    method mergeCompose (line 346) | public static IFn mergeCompose(final int nVals, final Object[] mergeFn...
    method longSamplerReduction (line 358) | public static Object longSamplerReduction(IFn rfn, Object acc, IFn.LL ...
    method doubleSamplerReduction (line 368) | public static Object doubleSamplerReduction(IFn rfn, Object acc, IFn.L...
    method samplerReduction (line 377) | public static Object samplerReduction(IFn rfn, Object acc, IFn sampler...

FILE: java/ham_fisted/ReindexList.java
  class ReindexList (line 11) | public class ReindexList implements IMutList, TypedList {
    method checkIndex (line 16) | static int checkIndex(final int idx, final int dlen) {
    method create (line 22) | public static ReindexList create(int[] idx, List d, IPersistentMap m) {
    method ReindexList (line 28) | public ReindexList(int[] idx, List d, IPersistentMap m) {
    method containedType (line 34) | public Class containedType() { return data instanceof TypedList ? ((Ty...
    method size (line 35) | public int size() { return indexes.length; }
    method get (line 36) | public Object get(int idx) {
    method set (line 40) | @SuppressWarnings("unchecked")
    method subList (line 45) | public ReindexList subList(int sidx, int eidx) {
    method indexComparator (line 48) | @SuppressWarnings("unchecked")
    method indexComparator (line 65) | @SuppressWarnings("unchecked")
    method meta (line 83) | public IPersistentMap meta() { return meta; }
    method withMeta (line 84) | public ReindexList withMeta(IPersistentMap m) {
    method reindex (line 87) | public List reindex(int[] newIndexes) {
    class MutReindexList (line 107) | public static class MutReindexList extends ReindexList {
      method MutReindexList (line 109) | public MutReindexList(int[] indexes, IMutList ml, IPersistentMap met...
      method getLong (line 113) | public long getLong(int idx) {
      method setLong (line 117) | public void setLong(int idx, long nv) {
      method getDouble (line 121) | public double getDouble(int idx) {
      method setDouble (line 125) | public void setDouble(int idx, double nv) {

FILE: java/ham_fisted/ReverseList.java
  class ReverseList (line 8) | public class ReverseList implements IMutList, TypedList {
    method ReverseList (line 16) | public ReverseList(List _data, IPersistentMap _meta) {
    method create (line 23) | public static ReverseList create(List data, IPersistentMap meta) {
    method toString (line 27) | public String toString() { return Transformables.sequenceToString(this...
    method hashCode (line 28) | public int hashCode() { return hasheq(); }
    method hasheq (line 29) | public int hasheq() {
    method equals (line 35) | public boolean equals(Object other) { return equiv(other); }
    method containedType (line 36) | public Class containedType() { return data instanceof TypedList ? ((Ty...
    method size (line 37) | public int size() { return nElems; }
    method get (line 38) | public Object get(int idx) { if(idx < 0) idx += nElems; return data.ge...
    method subList (line 39) | public ReverseList subList(int sidx, int eidx) {
    method reverse (line 44) | public List reverse() { return data instanceof IObj ? (List)((IObj)dat...
    method meta (line 45) | public IPersistentMap meta() { return meta; }
    method withMeta (line 46) | public ReverseList withMeta(IPersistentMap m) { return new ReverseList...
    class MutReverseList (line 49) | public static class MutReverseList extends ReverseList {
      method MutReverseList (line 51) | public MutReverseList(IMutList ml, IPersistentMap meta) {
      method getLong (line 55) | public long getLong(int idx) {
      method getDouble (line 58) | public double getDouble(int idx) {

FILE: java/ham_fisted/SetOps.java
  type SetOps (line 6) | public interface SetOps {
    method union (line 7) | Set union(Collection rhs);
    method intersection (line 8) | Set intersection(Set rhs);
    method difference (line 9) | Set difference(Set rhs);

FILE: java/ham_fisted/StringCollection.java
  class StringCollection (line 18) | public class StringCollection implements IMutList<Character> {
    method StringCollection (line 20) | public StringCollection(String _cs) {
    method size (line 23) | public final int size() { return cs.length(); }
    method get (line 24) | public final Character get(int idx) { return cs.charAt(idx); }
    method subList (line 25) | public final IMutList<Character> subList(int startidx, int endidx) {
    method fillArray (line 28) | public final Object[] fillArray(Object[] data) {
    method reduce (line 37) | public Object reduce(IFn rfn) {
    method reduce (line 46) | public Object reduce(IFn rfn, Object acc) {

FILE: java/ham_fisted/Sum.java
  class Sum (line 13) | public final class Sum implements Consumers.IDerefDoubleConsumer, Reducible
    method sumWithCompensation (line 34) | public void sumWithCompensation(double value) {
    method computeFinalSum (line 42) | public double computeFinalSum() {
    method Sum (line 51) | public Sum(double _d0, double _d1, double _simpleSum, long _nElems) {
    method Sum (line 57) | public Sum() {
    method acceptDouble (line 60) | public void acceptDouble(double data) {
    method merge (line 66) | public void merge(Sum other) {
    method reduce (line 72) | public Sum reduce(Reducible other) {
    method deref (line 78) | public Object deref() {
    class SimpleSum (line 82) | public static class SimpleSum implements Consumers.IDerefDoubleConsume...
      method SimpleSum (line 85) | public SimpleSum() { simpleSum = 0.0; }
      method SimpleSum (line 86) | public SimpleSum(SimpleSum o) { simpleSum = o.simpleSum; }
      method acceptDouble (line 87) | public void acceptDouble(double val) { simpleSum += val; }
      method reduce (line 88) | public SimpleSum reduce(Reducible other) {
      method deref (line 93) | public Object deref() {

FILE: java/ham_fisted/Transformables.java
  class Transformables (line 49) | public class Transformables {
    method invoke (line 52) | public Object invoke() {
    method toIterable (line 57) | public static final Iterable toIterable(Object obj) {
    type IMapable (line 63) | public interface IMapable extends Iterable, IObj {
      method map (line 64) | default IMapable map(IFn fn) {
      method filter (line 67) | default IMapable filter(IFn fn) {
      method cat (line 70) | default IMapable cat(Iterable iters) {
    method truthy (line 74) | public static boolean truthy(final Object obj) {
    method not (line 77) | public static boolean not(final Object obj) {
    method not (line 80) | public static boolean not(final boolean v) {
    method toReductionFn (line 83) | public static IFn toReductionFn(Object rfn) {
    method toLongReductionFn (line 105) | public static IFn.OLO toLongReductionFn(Object rfn) {
    method toDoubleReductionFn (line 125) | public static IFn.ODO toDoubleReductionFn(Object rfn) {
    method iterCount (line 145) | public static int iterCount(Iterator iter) {
    method mapReducer (line 153) | public static IFn mapReducer(final IFn rfn, final IFn mapFn) {
    method longMapReducer (line 165) | public static IFn longMapReducer(final IFn rfn, final IFn mapFn) {
    method invoke (line 212) | public Object invoke() { return rfn.invoke(); }
    method invoke (line 213) | public Object invoke(Object res) { return rfn.invoke(res); }
    method invokePrim (line 214) | public Object invokePrim(Object lhs, long v) {
    method applyTo (line 217) | public Object applyTo(Object arglist) {
    method invoke (line 227) | public Object invoke() { return rfn.invoke(); }
    method invoke (line 228) | public Object invoke(Object res) { return rfn.invoke(res); }
    method invoke (line 229) | public Object invoke(Object lhs, Object v) {
    method applyTo (line 232) | public Object applyTo(Object arglist) {
    method invoke (line 242) | public Object invoke() { return rfn.invoke(); }
    method invoke (line 243) | public Object invoke(Object res) { return rfn.invoke(res); }
    method invokePrim (line 244) | public Object invokePrim(Object lhs, double rhs) {
    method applyTo (line 247) | public Object applyTo(Object arglist) {
    method invoke (line 257) | public Object invoke() { return rfn.invoke(); }
    method invoke (line 258) | public Object invoke(Object res) { return rfn.invoke(res); }
    method invoke (line 259) | public Object invoke(Object lhs, Object v) {
    method applyTo (line 262) | public Object applyTo(Object arglist) {
    method invoke (line 272) | public Object invoke() { return rfn.invoke(); }
    method invoke (line 273) | public Object invoke(Object res) { return rfn.invoke(res); }
    method invokePrim (line 274) | public Object invokePrim(Object lhs, double v) {
    method applyTo (line 277) | public Object applyTo(Object arglist) {
    method invoke (line 287) | public Object invoke() { return rfn.invoke(); }
    method invoke (line 288) | public Object invoke(Object res) { return rfn.invoke(res); }
    method invokePrim (line 289) | public Object invokePrim(Object lhs, long v) {
    method applyTo (line 292) | public Object applyTo(Object arglist) {
    method typedMapReducer (line 300) | public static IFn typedMapReducer(IFn rfn, IFn mapFn) {
    method singleMapReduce (line 319) | public static Object singleMapReduce(final Object item, final IFn rfn,
    method seqEquiv (line 324) | public static boolean seqEquiv(Seqable ss, Object o){
    method seqHashCode (line 332) | public static int seqHashCode(Seqable ss) {
    type IterableSeq (line 339) | public interface IterableSeq extends Collection, Seqable, IMapable, IT...
      method hasheq (line 341) | default int hasheq() { return Murmur3.hashOrdered(this); }
      method equiv (line 342) | default boolean equiv(Object o) { return seqEquiv(this, o); }
      method count (line 343) | default int count() {
      method cons (line 352) | default IPersistentCollection cons(Object o) {
      method empty (line 355) | default IPersistentCollection empty() {
      method forEach (line 358) | @SuppressWarnings("unchecked")
      method seq (line 362) | default ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(iterator...
    class MapIterable (line 365) | public static class MapIterable
      method MapIterable (line 371) | public MapIterable(IFn _fn, IPersistentMap _meta, Object... _its) {
      method createSingle (line 376) | public static MapIterable createSingle(IFn fn, IPersistentMap meta, ...
      method MapIterable (line 379) | public MapIterable(MapIterable o, IPersistentMap m) {
      method toString (line 384) | public String toString() { return sequenceToString(this); }
      method isEmpty (line 385) | public boolean isEmpty() {
      method size (line 388) | public int size() {
      class SingleIterator (line 391) | static class SingleIterator implements Iterator {
        method SingleIterator (line 394) | public SingleIterator(IFn _fn, Iterator it) {
        method hasNext (line 398) | public boolean hasNext() { return iter.hasNext(); }
        method next (line 399) | public Object next() { return fn.invoke(iter.next()); }
      class DualIterator (line 402) | static class DualIterator implements Iterator {
        method DualIterator (line 406) | public DualIterator(IFn f, Iterator l, Iterator r) {
        method hasNext (line 411) | public boolean hasNext() { return lhs.hasNext() && rhs.hasNext(); }
        method next (line 412) | public Object next() {
      method iterator (line 417) | public Iterator iterator() {
      method seq (line 449) | public ISeq seq() {
      method equals (line 452) | public boolean equals(Object o) { return equiv(o); }
      method hashCode (line 453) | public int hashCode(){ return hasheq(); }
      method map (line 455) | public MapIterable map(IFn nfn) {
      method meta (line 458) | public IPersistentMap meta() { return meta; }
      method withMeta (line 459) | public MapIterable withMeta(IPersistentMap m) {
      method reduce (line 462) | public Object reduce(IFn rfn, Object acc) {
      method parallelReduction (line 525) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
      method toArray (line 534) | public Object[] toArray() {
    class PredFn (line 538) | public static class PredFn implements IFnDef {
      method create (line 539) | static IFn create(IFn src, IFn dst) {
      method PredFn (line 588) | public PredFn(IFn sp, IFn dp) {
      method invoke (line 592) | public Object invoke(Object v) {
    class FilterIterable (line 596) | public static class FilterIterable
      method FilterIterable (line 602) | public FilterIterable(IFn _p, IPersistentMap _meta, Object _i) {
      method FilterIterable (line 607) | public FilterIterable(FilterIterable o, IPersistentMap m) {
      method toString (line 612) | public String toString() { return sequenceToString(this); }
      method isEmpty (line 613) | public boolean isEmpty() {
      method size (line 616) | public int size() { return iterCount(iterator()); }
      class FilterIterator (line 617) | static class FilterIterator implements Iterator {
        method FilterIterator (line 621) | public FilterIterator(Iterator _i, IFn p) {
        method advance (line 626) | void advance() {
        method hasNext (line 636) | public boolean hasNext() { return nextObj != null; }
        method next (line 637) | public Object next() {
      method iterator (line 645) | public Iterator iterator() {
      method hashCode (line 649) | public int hashCode(){ return hasheq(); }
      method equals (line 650) | public boolean equals(Object o) { return equiv(o); }
      method seq (line 651) | public ISeq seq() {
      method filter (line 654) | public IMapable filter(IFn nfn) {
      method meta (line 657) | public IPersistentMap meta() { return meta; }
      method withMeta (line 658) | public FilterIterable withMeta(IPersistentMap m) {
      method typedReducer (line 661) | @SuppressWarnings("unchecked")
      method reduce (line 722) | public Object reduce(final IFn rfn, final Object init) {
      method parallelReduction (line 725) | public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,
      method toArray (line 730) | public Object[] toArray() {
    class CatIterable (line 735) | public static class CatIterable
      method CatIterable (line 742) | public CatIterable(IPersistentMap _meta, ParallelOptions.CatParallel...
      method CatIterable (line 747) | public CatIterable(IPersistentMap _meta, Iterable[] f) {
      method CatIterable (line 752) | public CatIterable(Iterable arglist) {
     
Condensed preview — 198 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,147K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 18,
    "preview": "github: cnuernber\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1452,
    "preview": "name: Automated tests\n\non:\n  push:\n\njobs:\n  test:\n    runs-on: ubuntu-22.04\n    steps:\n    - uses: actions/checkout@v3\n "
  },
  {
    "path": ".gitignore",
    "chars": 90,
    "preview": ".cpcache\ntarget\n.nrepl-port\npom.xml\n*.asc\nissue-data\njdk-*\n.clj-kondo\n.lsp\n.dir-locals.el\n"
  },
  {
    "path": ".mise.toml",
    "chars": 28,
    "preview": "[tools]\njava = \"corretto-8\"\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 25531,
    "preview": "# 3.029\n * Much more thorough support for spliterators and forkjoinpool. See spliterator and fjp namespaces\n   respectiv"
  },
  {
    "path": "LICENSE",
    "chars": 1081,
    "preview": "The MIT License (MIT)\n\nCopyright © 2021 Chris Nuernberger\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "README.md",
    "chars": 19109,
    "preview": "# HAM-Fisted\n\n[![Clojars Project](https://clojars.org/com.cnuernber/ham-fisted/latest-version.svg)](https://clojars.org/"
  },
  {
    "path": "build.clj",
    "chars": 1874,
    "preview": "(ns build\n  (:require [clojure.tools.build.api :as b]\n            [clojure.edn :as edn])\n  (:refer-clojure :exclude [com"
  },
  {
    "path": "codegen/gen_prim_invoke.clj",
    "chars": 2336,
    "preview": "(ns gen-prim-invoke\n  (:require [clojure.java.io :as io]\n            [ham-fisted.lazy-noncaching :as lznc]\n            ["
  },
  {
    "path": "deps.edn",
    "chars": 4647,
    "preview": "{:paths [\"src\" \"resources\" \"target/classes\"]\n :deps {it.unimi.dsi/fastutil-core {:mvn/version \"8.5.14\"}\n        com.gith"
  },
  {
    "path": "dev/resources/logback.xml",
    "chars": 426,
    "preview": "<configuration debug=\"false\">\n  <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n    <!-- encoders a"
  },
  {
    "path": "dev/src/ham_fisted/analysis.clj",
    "chars": 4885,
    "preview": "(ns ham-fisted.analysis\n  (:require [clojure.edn :as edn]\n            [charred.api :as charred]\n            [applied-sci"
  },
  {
    "path": "dev/src/ham_fisted/benchmark.clj",
    "chars": 327,
    "preview": "(ns ham-fisted.benchmark\n  (:require [criterium.core :as c]))\n\n\n(defmacro benchmark-us\n  \"Benchmark an op, returning a m"
  },
  {
    "path": "dev/src/ham_fisted/protocol_perf.clj",
    "chars": 5752,
    "preview": "(ns ham-fisted.protocol-perf\n  (:require [ham-fisted.defprotocol :as hamf-defproto]\n            [ham-fisted.protocols :a"
  },
  {
    "path": "dev/src/perftest.clj",
    "chars": 26011,
    "preview": "(ns perftest\n  (:require [ham-fisted.api :as hamf]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted"
  },
  {
    "path": "docs/Reductions.html",
    "chars": 24680,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>Reductions</title><script async=\"true\" src=\""
  },
  {
    "path": "docs/css/default.css",
    "chars": 9428,
    "preview": "@import url('https://fonts.googleapis.com/css?family=PT+Sans');\n\nbody {\n    font-family: 'PT Sans', Helvetica, sans-seri"
  },
  {
    "path": "docs/ham-fisted.api.html",
    "chars": 114249,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.api documentation</title><script "
  },
  {
    "path": "docs/ham-fisted.bloom-filter.html",
    "chars": 12715,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.bloom-filter documentation</title"
  },
  {
    "path": "docs/ham-fisted.defprotocol.html",
    "chars": 16577,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.defprotocol documentation</title>"
  },
  {
    "path": "docs/ham-fisted.fjp.html",
    "chars": 15053,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.fjp documentation</title><script "
  },
  {
    "path": "docs/ham-fisted.function.html",
    "chars": 23333,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.function documentation</title><sc"
  },
  {
    "path": "docs/ham-fisted.hlet.html",
    "chars": 9017,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.hlet documentation</title><script"
  },
  {
    "path": "docs/ham-fisted.iterator.html",
    "chars": 19066,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.iterator documentation</title><sc"
  },
  {
    "path": "docs/ham-fisted.lazy-noncaching.html",
    "chars": 39976,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.lazy-noncaching documentation</ti"
  },
  {
    "path": "docs/ham-fisted.mut-map.html",
    "chars": 8948,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.mut-map documentation</title><scr"
  },
  {
    "path": "docs/ham-fisted.primitive-invoke.html",
    "chars": 337396,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.primitive-invoke documentation</t"
  },
  {
    "path": "docs/ham-fisted.process.html",
    "chars": 12030,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.process documentation</title><scr"
  },
  {
    "path": "docs/ham-fisted.profile.html",
    "chars": 7245,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.profile documentation</title><scr"
  },
  {
    "path": "docs/ham-fisted.protocols.html",
    "chars": 34523,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.protocols documentation</title><s"
  },
  {
    "path": "docs/ham-fisted.reduce.html",
    "chars": 33726,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.reduce documentation</title><scri"
  },
  {
    "path": "docs/ham-fisted.set.html",
    "chars": 17538,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.set documentation</title><script "
  },
  {
    "path": "docs/ham-fisted.spliterator.html",
    "chars": 10699,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.spliterator documentation</title>"
  },
  {
    "path": "docs/highlight/solarized-light.css",
    "chars": 1145,
    "preview": "/*\n\nOrginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>\n\n*/\n\n.hljs {\n  display: block"
  },
  {
    "path": "docs/index.html",
    "chars": 100408,
    "preview": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>Ham-Fisted 3.029</title><script async=\"true\""
  },
  {
    "path": "docs/js/page_effects.js",
    "chars": 3565,
    "preview": "function visibleInParent(element) {\n    var position = $(element).position().top\n    return position > -50 && position <"
  },
  {
    "path": "java/ham_fisted/ArrayHelpers.java",
    "chars": 3994,
    "preview": "package ham_fisted;\n\n\n\npublic class ArrayHelpers\n{\n  public static Object checkedAget(Object[] data, int nelems, int idx"
  },
  {
    "path": "java/ham_fisted/ArrayImmutList.java",
    "chars": 12223,
    "preview": "package ham_fisted;\n\n\nimport static ham_fisted.ChunkedList.*;\nimport static ham_fisted.HashProviders.*;\n\nimport java.uti"
  },
  {
    "path": "java/ham_fisted/ArrayLists.java",
    "chars": 88017,
    "preview": "package ham_fisted;\n\n\nimport java.util.List;\nimport java.util.Arrays;\nimport java.lang.reflect.Array;\nimport java.util.C"
  },
  {
    "path": "java/ham_fisted/ArraySection.java",
    "chars": 723,
    "preview": "package ham_fisted;\n\n\n\npublic class ArraySection\n{\n  public final Object array;\n  public final int sidx;\n  public final "
  },
  {
    "path": "java/ham_fisted/BatchReducer.java",
    "chars": 1353,
    "preview": "package ham_fisted;\n\nimport clojure.lang.Sequential;\nimport clojure.lang.IDeref;\nimport clojure.lang.IFn;\nimport clojure"
  },
  {
    "path": "java/ham_fisted/BatchedList.java",
    "chars": 1331,
    "preview": "package ham_fisted;\n\nimport clojure.lang.IDeref;\n\npublic class BatchedList implements IMutList, IDeref {\n  public static"
  },
  {
    "path": "java/ham_fisted/BiFunctions.java",
    "chars": 258,
    "preview": "package ham_fisted;\n\n\nimport java.util.function.BiFunction;\n\n\npublic class BiFunctions {\n  public static final BiFunctio"
  },
  {
    "path": "java/ham_fisted/BlockSplitBloomFilter.java",
    "chars": 8277,
    "preview": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOT"
  },
  {
    "path": "java/ham_fisted/Casts.java",
    "chars": 4171,
    "preview": "package ham_fisted;\n\n\n\nimport clojure.lang.Util;\nimport clojure.lang.RT;\n\n\npublic class Casts {\n  public static boolean "
  },
  {
    "path": "java/ham_fisted/ChunkedList.java",
    "chars": 22688,
    "preview": "package ham_fisted;\n\nimport static ham_fisted.IntegerOps.*;\n\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport "
  },
  {
    "path": "java/ham_fisted/CljHash.java",
    "chars": 3586,
    "preview": "package ham_fisted;\n\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.List;\nimport java.util.Iterator;\nimpo"
  },
  {
    "path": "java/ham_fisted/ConstList.java",
    "chars": 3675,
    "preview": "package ham_fisted;\n\nimport java.util.Comparator;\nimport java.util.Random;\nimport java.util.List;\nimport java.util.Array"
  },
  {
    "path": "java/ham_fisted/ConsumerAccumulators.java",
    "chars": 1090,
    "preview": "package ham_fisted;\n\n\npublic class ConsumerAccumulators {\n  public static class DoubleConsumerAccumulator implements IFn"
  },
  {
    "path": "java/ham_fisted/Consumers.java",
    "chars": 7715,
    "preview": "package ham_fisted;\n\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.func"
  },
  {
    "path": "java/ham_fisted/CtxIter.java",
    "chars": 921,
    "preview": "package ham_fisted;\n\nimport java.util.Iterator;\nimport java.util.function.Supplier;\n\npublic class CtxIter implements Ite"
  },
  {
    "path": "java/ham_fisted/DoubleMutList.java",
    "chars": 4437,
    "preview": "package ham_fisted;\n\nimport java.util.Random;\nimport java.util.List;\nimport java.util.Comparator;\nimport java.util.Split"
  },
  {
    "path": "java/ham_fisted/FJTask.java",
    "chars": 407,
    "preview": "package ham_fisted;\n\nimport clojure.lang.IFn;\nimport clojure.lang.IDeref;\nimport clojure.lang.Delay;\nimport java.util.co"
  },
  {
    "path": "java/ham_fisted/FMapEntry.java",
    "chars": 1338,
    "preview": "package ham_fisted;\n\n\nimport java.util.Map;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IMapEntry;\n\npublic c"
  },
  {
    "path": "java/ham_fisted/ForkJoinPatterns.java",
    "chars": 1357,
    "preview": "package ham_fisted;\n\nimport clojure.lang.IFn;\nimport clojure.lang.Delay;\nimport clojure.lang.IDeref;\nimport clojure.java"
  },
  {
    "path": "java/ham_fisted/HashBase.java",
    "chars": 6909,
    "preview": "package ham_fisted;\n\n\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.Spliterator;\nimport java.util"
  },
  {
    "path": "java/ham_fisted/HashMap.java",
    "chars": 15077,
    "preview": "package ham_fisted;\n\n\n\nimport java.util.Map;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.functi"
  },
  {
    "path": "java/ham_fisted/HashNode.java",
    "chars": 2456,
    "preview": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.Iterator;\nimport clojure.lang.IMapEntry;\nimport ham_fisted.I"
  },
  {
    "path": "java/ham_fisted/HashProvider.java",
    "chars": 291,
    "preview": "package ham_fisted;\n\n\nimport java.util.Objects;\n\n\npublic interface HashProvider {\n  public default int hash(Object obj) "
  },
  {
    "path": "java/ham_fisted/HashProviders.java",
    "chars": 1038,
    "preview": "package ham_fisted;\n\nimport clojure.lang.Util;\nimport clojure.lang.IHashEq;\n\n\npublic class HashProviders {\n  public stat"
  },
  {
    "path": "java/ham_fisted/HashSet.java",
    "chars": 7860,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.IPersistentMap;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.u"
  },
  {
    "path": "java/ham_fisted/IAMapEntry.java",
    "chars": 516,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.IMapEntry;\nimport java.util.Map;\n\npublic interface IAMapEntry extends Map.Entr"
  },
  {
    "path": "java/ham_fisted/IAPersistentMap.java",
    "chars": 871,
    "preview": "package ham_fisted;\n\nimport java.util.Map;\nimport clojure.lang.IEditableCollection;\nimport clojure.lang.IPersistentMap;\n"
  },
  {
    "path": "java/ham_fisted/IAPersistentSet.java",
    "chars": 585,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.IPersistentSet;\nimport clojure.lang.ITransientSet;\nimport clojure.lang.IEditab"
  },
  {
    "path": "java/ham_fisted/IATransientMap.java",
    "chars": 1333,
    "preview": "package ham_fisted;\n\n\nimport java.util.Map;\nimport clojure.lang.Indexed;\nimport clojure.lang.ITransientMap;\nimport cloju"
  },
  {
    "path": "java/ham_fisted/IATransientSet.java",
    "chars": 183,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.ITransientSet;\n\n\npublic interface IATransientSet extends ITransientSet {\n  def"
  },
  {
    "path": "java/ham_fisted/ICollectionDef.java",
    "chars": 1380,
    "preview": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.Objects;\nimport java.util"
  },
  {
    "path": "java/ham_fisted/IFnDef.java",
    "chars": 16227,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.IFn;\nimport clojure.lang.ISeq;\nimport clojure.lang.Util;\nimport clojure.lang.R"
  },
  {
    "path": "java/ham_fisted/IMap.java",
    "chars": 6157,
    "preview": "package ham_fisted;\n\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Iterator;\nimport java.util.Spliterato"
  },
  {
    "path": "java/ham_fisted/IMutList.java",
    "chars": 21467,
    "preview": "package ham_fisted;\n\n\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.util.Iterator;\nimport java.util."
  },
  {
    "path": "java/ham_fisted/ISeqDef.java",
    "chars": 4702,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.ISeq;\nimport clojure.lang.Sequential;\nimport clojure.lang.IHashEq;\nimport cloj"
  },
  {
    "path": "java/ham_fisted/ISet.java",
    "chars": 1505,
    "preview": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport java.util.Set;\nimport java.util.Iterator;\nimport java.util.fun"
  },
  {
    "path": "java/ham_fisted/ITypedReduce.java",
    "chars": 1727,
    "preview": "package ham_fisted;\n\n\nimport java.util.function.DoubleBinaryOperator;\nimport java.util.function.LongBinaryOperator;\nimpo"
  },
  {
    "path": "java/ham_fisted/ImmutList.java",
    "chars": 8903,
    "preview": "package ham_fisted;\n\n\nimport static ham_fisted.ChunkedList.*;\nimport java.util.List;\nimport java.util.Objects;\nimport ja"
  },
  {
    "path": "java/ham_fisted/ImmutSort.java",
    "chars": 1185,
    "preview": "package ham_fisted;\n\n\nimport java.util.List;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport it.unimi.dsi.f"
  },
  {
    "path": "java/ham_fisted/IndexedConsumer.java",
    "chars": 105,
    "preview": "package ham_fisted;\n\n\npublic interface IndexedConsumer {\n  public void accept(long index, Object val);\n}\n"
  },
  {
    "path": "java/ham_fisted/IndexedDoubleConsumer.java",
    "chars": 109,
    "preview": "package ham_fisted;\n\n\npublic interface IndexedDoubleConsumer {\n  public void accept(long idx, double val);\n}\n"
  },
  {
    "path": "java/ham_fisted/IndexedLongConsumer.java",
    "chars": 105,
    "preview": "package ham_fisted;\n\n\npublic interface IndexedLongConsumer {\n  public void accept(long idx, long val);\n}\n"
  },
  {
    "path": "java/ham_fisted/IntegerOps.java",
    "chars": 3655,
    "preview": "package ham_fisted;\n\n\n/** \n * Static 32 bit and 64 bit integer operations specific to the bitmap trie.\n */\npublic final "
  },
  {
    "path": "java/ham_fisted/Iter.java",
    "chars": 1325,
    "preview": "package ham_fisted;\n\nimport java.util.Iterator;\n\npublic interface Iter {\n  Object get();\n  Iter next();\n\n  public static"
  },
  {
    "path": "java/ham_fisted/LazyChunkedSeq.java",
    "chars": 2543,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.IFn;\nimport clojure.lang.IChunkedSeq;\nimport clojure.lang.IChunk;\nimport cloju"
  },
  {
    "path": "java/ham_fisted/LinkedHashMap.java",
    "chars": 4124,
    "preview": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Iterator;\nimport java.util.NoSuchEleme"
  },
  {
    "path": "java/ham_fisted/LinkedHashNode.java",
    "chars": 1599,
    "preview": "package ham_fisted;\n\n\npublic class LinkedHashNode extends HashNode {\n  //Less recently modified\n  LinkedHashNode prevLin"
  },
  {
    "path": "java/ham_fisted/LongAccum.java",
    "chars": 434,
    "preview": "package ham_fisted;\n\n\n\nimport java.util.function.LongConsumer;\nimport clojure.lang.IDeref;\n\n\n\npublic class LongAccum imp"
  },
  {
    "path": "java/ham_fisted/LongHashBase.java",
    "chars": 6805,
    "preview": "package ham_fisted;\n\n\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.Spliterator;\nimport java.util"
  },
  {
    "path": "java/ham_fisted/LongHashMap.java",
    "chars": 12032,
    "preview": "package ham_fisted;\n\n\n\nimport java.util.Map;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.functi"
  },
  {
    "path": "java/ham_fisted/LongHashNode.java",
    "chars": 2481,
    "preview": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.Iterator;\nimport clojure.lang.IMapEntry;\nimport ham_fisted.I"
  },
  {
    "path": "java/ham_fisted/LongMutList.java",
    "chars": 4514,
    "preview": "package ham_fisted;\n\nimport java.util.Random;\nimport java.util.List;\nimport java.util.Comparator;\nimport java.util.funct"
  },
  {
    "path": "java/ham_fisted/MapFn.java",
    "chars": 8423,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.IFn;\nimport clojure.lang.ISeq;\n\npublic class MapFn implements IFnDef {\n  publi"
  },
  {
    "path": "java/ham_fisted/MapForward.java",
    "chars": 4662,
    "preview": "package ham_fisted;\n\n\nimport java.util.Map;\nimport java.util.Iterator;\nimport java.util.Spliterator;\nimport java.util.Se"
  },
  {
    "path": "java/ham_fisted/MapSetOps.java",
    "chars": 463,
    "preview": "package ham_fisted;\n\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Collection;\nimport java.util.function"
  },
  {
    "path": "java/ham_fisted/MergeIterator.java",
    "chars": 6413,
    "preview": "package ham_fisted;\n\nimport java.util.Iterator;\nimport java.util.Comparator;\nimport java.util.ArrayList;\nimport java.uti"
  },
  {
    "path": "java/ham_fisted/MethodImplCache.java",
    "chars": 3719,
    "preview": "/**\n *   Copyright (c) Rich Hickey. All rights reserved.\n *   The use and distribution terms for this software are cover"
  },
  {
    "path": "java/ham_fisted/MutList.java",
    "chars": 15582,
    "preview": "package ham_fisted;\n\nimport static ham_fisted.ChunkedList.*;\n\nimport java.util.List;\nimport java.util.Objects;\nimport ja"
  },
  {
    "path": "java/ham_fisted/MutTreeList.java",
    "chars": 4196,
    "preview": "package ham_fisted;\n\nimport java.util.Arrays;\nimport clojure.lang.Box;\nimport clojure.lang.IPersistentMap;\nimport clojur"
  },
  {
    "path": "java/ham_fisted/MutableMap.java",
    "chars": 130,
    "preview": "package ham_fisted;\n\n//Marker interface indicating that merge, compute, put, etc. are safe to use.\npublic interface Muta"
  },
  {
    "path": "java/ham_fisted/ObjArray.java",
    "chars": 4991,
    "preview": "package ham_fisted;\n\n\nimport java.util.Arrays;\nimport java.util.Iterator;\n\n\npublic class ObjArray {\n  public static fina"
  },
  {
    "path": "java/ham_fisted/ParallelOptions.java",
    "chars": 1731,
    "preview": "package ham_fisted;\n\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.ForkJoinPool;\n\n\npublic cl"
  },
  {
    "path": "java/ham_fisted/PartitionByInner.java",
    "chars": 2510,
    "preview": "package ham_fisted;\n\n\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport java.util.function.BiPr"
  },
  {
    "path": "java/ham_fisted/PersistentHashMap.java",
    "chars": 3321,
    "preview": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Collection;\nimport java.util.function."
  },
  {
    "path": "java/ham_fisted/PersistentHashSet.java",
    "chars": 1167,
    "preview": "package ham_fisted;\n\n\nimport java.util.Set;\nimport java.util.Collection;\nimport clojure.lang.IPersistentMap;\nimport cloj"
  },
  {
    "path": "java/ham_fisted/PersistentLongHashMap.java",
    "chars": 2099,
    "preview": "package ham_fisted;\n\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport java.util.Collecti"
  },
  {
    "path": "java/ham_fisted/PersistentVector.java",
    "chars": 83,
    "preview": "package ham_fisted;\n\n\nimport java.util.Arrays;\n\npublic class PersistentVector {\n\n}\n"
  },
  {
    "path": "java/ham_fisted/ROHashMap.java",
    "chars": 1437,
    "preview": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimp"
  },
  {
    "path": "java/ham_fisted/ROHashSet.java",
    "chars": 572,
    "preview": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport clojure.lang.IPersistentMap;\n\n\npublic class ROHashSet extends "
  },
  {
    "path": "java/ham_fisted/ROLongHashMap.java",
    "chars": 1453,
    "preview": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimp"
  },
  {
    "path": "java/ham_fisted/RandomAccessSpliterator.java",
    "chars": 4239,
    "preview": "package ham_fisted;\n\nimport java.util.Spliterator;\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.uti"
  },
  {
    "path": "java/ham_fisted/RangeList.java",
    "chars": 346,
    "preview": "package ham_fisted;\n\n\nimport java.util.List;\n\n\npublic interface RangeList {\n  public void fillRange(long startidx, long "
  },
  {
    "path": "java/ham_fisted/Ranges.java",
    "chars": 8718,
    "preview": "package ham_fisted;\n\n\nimport java.util.Random;\nimport java.util.List;\nimport java.util.function.LongConsumer;\nimport jav"
  },
  {
    "path": "java/ham_fisted/Reducible.java",
    "chars": 297,
    "preview": "package ham_fisted;\n\n\nimport java.util.Iterator;\n\n\npublic interface Reducible\n{\n  default Reducible reduceIter(Iterator<"
  },
  {
    "path": "java/ham_fisted/Reductions.java",
    "chars": 11798,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport clojure.lang.IReduceInit;\nimport clojure.l"
  },
  {
    "path": "java/ham_fisted/ReindexList.java",
    "chars": 4075,
    "preview": "package ham_fisted;\n\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Comparator;\nimport it.unimi.dsi.f"
  },
  {
    "path": "java/ham_fisted/ReverseList.java",
    "chars": 1903,
    "preview": "package ham_fisted;\n\nimport java.util.List;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IObj;\n\n\npublic class"
  },
  {
    "path": "java/ham_fisted/SetOps.java",
    "chars": 186,
    "preview": "package ham_fisted;\n\nimport java.util.Set;\nimport java.util.Collection;\n\npublic interface SetOps {\n  Set union(Collectio"
  },
  {
    "path": "java/ham_fisted/StringCollection.java",
    "chars": 1572,
    "preview": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.uti"
  },
  {
    "path": "java/ham_fisted/Sum.java",
    "chars": 2740,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.IDeref;\nimport clojure.lang.Keyword;\nimport clojure.lang.IReduceInit;\nimport c"
  },
  {
    "path": "java/ham_fisted/Transformables.java",
    "chars": 43096,
    "preview": "package ham_fisted;\n\nimport java.util.List;\nimport java.util.AbstractCollection;\nimport java.util.Collection;\nimport jav"
  },
  {
    "path": "java/ham_fisted/TransientHashMap.java",
    "chars": 1497,
    "preview": "package ham_fisted;\n\nimport java.util.function.BiFunction;\nimport java.util.Map;\nimport clojure.lang.Indexed;\nimport clo"
  },
  {
    "path": "java/ham_fisted/TransientHashSet.java",
    "chars": 734,
    "preview": "package ham_fisted;\n\nimport clojure.lang.IPersistentMap;\n\npublic class TransientHashSet extends ROHashSet implements IAT"
  },
  {
    "path": "java/ham_fisted/TransientList.java",
    "chars": 3661,
    "preview": "package ham_fisted;\n\nimport static ham_fisted.IntegerOps.*;\n\nimport clojure.lang.ITransientVector;\nimport clojure.lang.R"
  },
  {
    "path": "java/ham_fisted/TransientLongHashMap.java",
    "chars": 1351,
    "preview": "package ham_fisted;\n\nimport java.util.Map;\nimport clojure.lang.Indexed;\nimport clojure.lang.ITransientMap;\nimport clojur"
  },
  {
    "path": "java/ham_fisted/TreeList.java",
    "chars": 5387,
    "preview": "package ham_fisted;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.List;\nimport java.util.Comparator"
  },
  {
    "path": "java/ham_fisted/TreeListBase.java",
    "chars": 27924,
    "preview": "package ham_fisted;\n\nimport java.util.Iterator;\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.Sp"
  },
  {
    "path": "java/ham_fisted/TypedList.java",
    "chars": 110,
    "preview": "package ham_fisted;\n\n\npublic interface TypedList {\n  default Class containedType() { return Object.class; }\n}\n"
  },
  {
    "path": "java/ham_fisted/TypedNth.java",
    "chars": 989,
    "preview": "package ham_fisted;\n\n\nimport clojure.lang.RT;\n\n\npublic class TypedNth {\n  public static double dnth(Object v, long idx) "
  },
  {
    "path": "java/ham_fisted/UnsharedHashMap.java",
    "chars": 2434,
    "preview": "package ham_fisted;\n\n\nimport java.util.List;\nimport java.util.Map;\nimport clojure.lang.IPersistentMap;\nimport clojure.la"
  },
  {
    "path": "java/ham_fisted/UnsharedHashSet.java",
    "chars": 562,
    "preview": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport clojure.lang.IPersistentMap;\n\n\npublic class UnsharedHashSet ex"
  },
  {
    "path": "java/ham_fisted/UnsharedLongHashMap.java",
    "chars": 2501,
    "preview": "package ham_fisted;\n\nimport java.util.List;\nimport java.util.Map;\nimport clojure.lang.IPersistentMap;\nimport clojure.lan"
  },
  {
    "path": "java/ham_fisted/UpdateValues.java",
    "chars": 314,
    "preview": "package ham_fisted;\n\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport clojure.lang.IFn;\n"
  },
  {
    "path": "resources/clj-kondo.exports/cnuernber/ham-fisted/config.edn",
    "chars": 1947,
    "preview": "{:lint-as {ham-fisted.defprotocol/defprotocol clojure.core/defprotocol\n           ham-fisted.defprotocol/extend-protocol"
  },
  {
    "path": "resources/clj-kondo.exports/cnuernber/ham-fisted/hooks/ham_fisted.clj_kondo",
    "chars": 5537,
    "preview": "(ns hooks.ham-fisted\n  (:require [clj-kondo.hooks-api :as api]))\n\n(defn node-value\n  [node]\n  (when node\n    (api/sexpr "
  },
  {
    "path": "results/.keepme",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "results/concatv.edn",
    "chars": 1897,
    "preview": "[{:clj {:mean-μs 0.24780844090292262, :variance-μs 3.764414164768287E-12}, :hamf {:mean-μs 0.43340971203396683, :varianc"
  },
  {
    "path": "results/d00905c-chrisn-lt3-jdk-1.8.0_312.edn",
    "chars": 6188,
    "preview": "{:machine-name \"chrisn-lt3\",\n :git-sha \"d00905c\",\n :jdk-version \"1.8.0_312\",\n :dataset\n [{:n-elems 5,\n   :norm-factor-μs"
  },
  {
    "path": "results/d00905c-chrisn-lt3-jdk-17.0.1.edn",
    "chars": 6198,
    "preview": "{:machine-name \"chrisn-lt3\",\n :git-sha \"d00905c\",\n :jdk-version \"17.0.1\",\n :dataset\n [{:n-elems 5,\n   :norm-factor-μs 0."
  },
  {
    "path": "results/general-hashmap.edn",
    "chars": 17607,
    "preview": "[{:hamf-trie {:mean-μs 0.12737612204503088, :variance-μs 6.396591659858203E-11}, :java {:mean-μs 0.15931202460367855, :v"
  },
  {
    "path": "results/persistent-vector.edn",
    "chars": 8532,
    "preview": "[{:java {:mean-μs 0.08404675313017497, :variance-μs 5.070139825243536E-14}, :n-elems 4, :clj {:mean-μs 0.049819357966357"
  },
  {
    "path": "results/random-update.edn",
    "chars": 5184,
    "preview": "[{:hamf-trie {:mean-μs 7.473810371306137, :variance-μs 6.636768315602025E-9}, :java {:mean-μs 5.722913191296465, :varian"
  },
  {
    "path": "results/sort-by.edn",
    "chars": 1876,
    "preview": "[{:clj {:mean-μs 0.09368354713973853, :variance-μs 3.4749205456213755E-13}, :hamf {:mean-μs 0.14596828192467412, :varian"
  },
  {
    "path": "results/typed-parallel-reductions.edn",
    "chars": 1131,
    "preview": "[{:clj {:mean-μs 6.109750675343813, :variance-μs 6.1388779737180735E-9}, :hamf-untyped {:mean-μs 19.804417360560404, :va"
  },
  {
    "path": "results/typed-reductions-intel.edn",
    "chars": 2778,
    "preview": "[{:clj {:mean-μs 0.08083155079773072, :variance-μs 2.607437776221788E-13}, :clj-typed {:mean-μs 0.1103805778248939, :var"
  },
  {
    "path": "results/typed-reductions.edn",
    "chars": 2791,
    "preview": "[{:clj {:mean-μs 0.020973830885365856, :variance-μs 1.5389297939653883E-13}, :clj-typed {:mean-μs 0.03145851381475773, :"
  },
  {
    "path": "results/union-disj.edn",
    "chars": 5198,
    "preview": "[{:hamf-trie {:mean-μs 0.05387404263091655, :variance-μs 7.601879123779283E-12}, :java {:mean-μs 0.07206509120153398, :v"
  },
  {
    "path": "results/union-overlapping.edn",
    "chars": 5279,
    "preview": "[{:hamf-trie {:mean-μs 0.10502638201374732, :variance-μs 9.426261585611141E-14}, :java {:mean-μs 0.1791063653635941, :va"
  },
  {
    "path": "results/union-reduce-transient.edn",
    "chars": 2385,
    "preview": "[{:hamf-trans-long-map {:mean-μs 0.7412825333830333, :variance-μs 3.170731692172204E-10}, :hamf-hashmap {:mean-μs 0.8866"
  },
  {
    "path": "results/union-reduce.edn",
    "chars": 5120,
    "preview": "[{:hamf-trie {:mean-μs 1.7252145524853624, :variance-μs 2.011615888905509E-10}, :java {:mean-μs 38.32988724387806, :vari"
  },
  {
    "path": "results/update-values.edn",
    "chars": 5247,
    "preview": "[{:hamf-trie {:mean-μs 0.02327796051118421, :variance-μs 1.529798206229456E-12}, :java {:mean-μs 0.07847960494396915, :v"
  },
  {
    "path": "results/vec-equals.edn",
    "chars": 2315,
    "preview": "[{:clj {:mean-μs 0.013114838133872559, :variance-μs 8.516910019923821E-16}, :hamf {:mean-μs 0.013453478507802178, :varia"
  },
  {
    "path": "scripts/benchmark",
    "chars": 139,
    "preview": "#!/bin/bash\n\necho \"Building uberjar\"\nrm -rf target\nclj -T:build perftest\njava -Djdk.attach.allowAttachSelf -jar target/u"
  },
  {
    "path": "scripts/compile",
    "chars": 60,
    "preview": "#!/bin/bash\n\nrm -rf target/classes\nclojure -T:build compile\n"
  },
  {
    "path": "scripts/deploy",
    "chars": 182,
    "preview": "#!/bin/bash\n\nset -e\n\nscripts/run-tests\nrm -f pom.xml\nclj -T:build jar\ncp target/classes/META-INF/maven/com.cnuernber/ham"
  },
  {
    "path": "scripts/enable-jdk17",
    "chars": 344,
    "preview": "#!/bin/bash\n\nif [ ! -e jdk-17.0.1 ]; then\n    wget https://download.java.net/java/GA/jdk17.0.1/2a2082e5a09d4267845be0868"
  },
  {
    "path": "scripts/install",
    "chars": 139,
    "preview": "#!/bin/bash\n\nset -e\n\nscripts/run-tests\nclj -T:build jar\ncp target/classes/META-INF/maven/com.cnuernber/ham-fisted/pom.xm"
  },
  {
    "path": "scripts/koacha-test",
    "chars": 56,
    "preview": "#!/bin/bash\n\nscripts/compile\nclojure -M:dev:kaocha-test\n"
  },
  {
    "path": "scripts/lint",
    "chars": 208,
    "preview": "#!/bin/bash\n\nscripts/compile\nclojure -M:dev:test:clj-kondo --copy-configs --dependencies --parallel --lint \"$(clojure -A"
  },
  {
    "path": "scripts/reformat",
    "chars": 63,
    "preview": "#!/bin/bash\n\npushd src\nreformat\npopd\n\npushd test\nreformat\npopd\n"
  },
  {
    "path": "scripts/run-tests",
    "chars": 49,
    "preview": "#!/bin/bash\n\nscripts/compile\nclojure -M:dev:test\n"
  },
  {
    "path": "src/ham_fisted/alists.clj",
    "chars": 14489,
    "preview": "(ns ham-fisted.alists\n  \"Generic primitive array backed array-lists.  The pure clojure implementations are a bit\n  slowe"
  },
  {
    "path": "src/ham_fisted/api.clj",
    "chars": 94788,
    "preview": "(ns ham-fisted.api\n  \"Fast mutable and immutable associative data structures based on bitmap trie\n  hashmaps. Mutable pa"
  },
  {
    "path": "src/ham_fisted/bloom_filter.clj",
    "chars": 4452,
    "preview": "(ns ham-fisted.bloom-filter\n  \"Simple fast bloom filter based on apache parquet BlockSplitBloomFilter.\"\n  (:require [ham"
  },
  {
    "path": "src/ham_fisted/caffeine.clj",
    "chars": 5227,
    "preview": "(ns ham-fisted.caffeine\n  (:require [ham-fisted.function :as hamf-fn])\n  (:import [com.github.benmanes.caffeine.cache Ca"
  },
  {
    "path": "src/ham_fisted/datatypes.clj",
    "chars": 4303,
    "preview": "(ns ham-fisted.datatypes\n  (:require [ham-fisted.protocols :as protocols]\n            [ham-fisted.defprotocol :as hamf-d"
  },
  {
    "path": "src/ham_fisted/defprotocol.clj",
    "chars": 25138,
    "preview": "(ns ham-fisted.defprotocol\n  \"Alternative protocol implementation.\n\n  Major features:\n\n  * Allows subclasses to override"
  },
  {
    "path": "src/ham_fisted/fjp.clj",
    "chars": 6185,
    "preview": "(ns ham-fisted.fjp\n  \"Support for java.util.concurrent.ForkJoinPool-specific operations such as managed block and task f"
  },
  {
    "path": "src/ham_fisted/function.clj",
    "chars": 8857,
    "preview": "(ns ham-fisted.function\n  \"Helpers for working with [java.util.function](https://docs.oracle.com/javase/8/docs/api/java/"
  },
  {
    "path": "src/ham_fisted/hlet.clj",
    "chars": 5602,
    "preview": "(ns ham-fisted.hlet\n  \"Extensible let to allow efficient typed destructuring.\n\n  Registered Extensions:\n\n  `dbls` and `l"
  },
  {
    "path": "src/ham_fisted/impl.clj",
    "chars": 19692,
    "preview": "(ns ham-fisted.impl\n  (:require [ham-fisted.lazy-noncaching :refer [map concat] :as lznc]\n            [ham-fisted.protoc"
  },
  {
    "path": "src/ham_fisted/iterator.clj",
    "chars": 14164,
    "preview": "(ns ham-fisted.iterator\n  \"Generialized efficient pathways involving iterators.\"\n  (:require [ham-fisted.language :refer"
  },
  {
    "path": "src/ham_fisted/language.clj",
    "chars": 3627,
    "preview": "(ns ham-fisted.language\n  (:import [ham_fisted Transformables]\n           [ham_fisted ObjArray])\n  (:refer-clojure :excl"
  },
  {
    "path": "src/ham_fisted/lazy_caching.clj",
    "chars": 6563,
    "preview": "(ns ham-fisted.lazy-caching\n  (:require [ham-fisted.lazy-noncaching :as lznc])\n  (:import [java.util RandomAccess List I"
  },
  {
    "path": "src/ham_fisted/lazy_noncaching.clj",
    "chars": 49439,
    "preview": "(ns ham-fisted.lazy-noncaching\n  \"Lazy, noncaching implementation of many clojure.core functions.  There are several ben"
  },
  {
    "path": "src/ham_fisted/mut_map.clj",
    "chars": 1958,
    "preview": "(ns ham-fisted.mut-map\n  \"Functions for working with java's mutable map interface\"\n  (:require [ham-fisted.function :as "
  },
  {
    "path": "src/ham_fisted/primitive_invoke.clj",
    "chars": 92917,
    "preview": "(ns ham-fisted.primitive-invoke\n  \"For statically traced calls the Clojure compiler calls the primitive version of type-"
  },
  {
    "path": "src/ham_fisted/print.clj",
    "chars": 266,
    "preview": "(ns ham-fisted.print)\n\n\n(defmacro implement-tostring-print\n  \"Implement tostring printing for a particular type name.\"\n "
  },
  {
    "path": "src/ham_fisted/process.clj",
    "chars": 7206,
    "preview": "(ns ham-fisted.process\n  (:require [ham-fisted.iterator :as hamf-iter]\n            [ham-fisted.reduce :as hamf-rf]))\n\n(d"
  },
  {
    "path": "src/ham_fisted/profile.clj",
    "chars": 927,
    "preview": "(ns ham-fisted.profile\n  (:import [java.util Map]\n           [java.util.concurrent ConcurrentHashMap]))\n\n(set! *warn-on-"
  },
  {
    "path": "src/ham_fisted/protocols.clj",
    "chars": 5819,
    "preview": "(ns ham-fisted.protocols\n  (:require [ham-fisted.defprotocol :refer [defprotocol extend-protocol extend-type extend]:as "
  },
  {
    "path": "src/ham_fisted/reduce.clj",
    "chars": 25880,
    "preview": "(ns ham-fisted.reduce\n  \"Protocol-based parallel reduction architecture and helper functions.\"\n  (:require [ham-fisted.p"
  },
  {
    "path": "src/ham_fisted/set.clj",
    "chars": 8752,
    "preview": "(ns ham-fisted.set\n  (:require [ham-fisted.protocols :as hamf-proto]\n            [ham-fisted.api :as api]\n            [h"
  },
  {
    "path": "src/ham_fisted/spliterator.clj",
    "chars": 9199,
    "preview": "(ns ham-fisted.spliterator\n  \"Support for spliterator reduction and parallel reduction.\"\n  (:require [ham-fisted.protoco"
  },
  {
    "path": "src/ham_fisted/thread_local.clj",
    "chars": 270,
    "preview": "(ns ham-fisted.thread-local)\n\n(defn thread-local\n  \"Create a new thread local variable\"\n  (^ThreadLocal [] (thread-local"
  },
  {
    "path": "test/ham_fisted/api_test.clj",
    "chars": 12328,
    "preview": "(ns ham-fisted.api-test\n  (:require [clojure.test :refer [deftest is]]\n            [ham-fisted.api :as hamf]\n           "
  },
  {
    "path": "test/ham_fisted/bloom_filter_test.clj",
    "chars": 1042,
    "preview": "(ns ham-fisted.bloom-filter-test\n  (:require [ham-fisted.bloom-filter :as hamf-bf]\n            [clojure.test :refer [def"
  },
  {
    "path": "test/ham_fisted/cast_test.clj",
    "chars": 1504,
    "preview": "(ns ham-fisted.cast-test\n  (:require [ham-fisted.api :as api]\n            [ham-fisted.function :as hamf-fn]\n            "
  },
  {
    "path": "test/ham_fisted/defprotocol_test/examples.clj",
    "chars": 620,
    "preview": "(ns ham-fisted.defprotocol-test.examples\n  (:refer-clojure :exclude [defprotocol])\n  (:require [ham-fisted.defprotocol :"
  },
  {
    "path": "test/ham_fisted/defprotocol_test/hash_collisions_test.clj",
    "chars": 3698,
    "preview": "(ns ham-fisted.defprotocol-test.hash-collisions-test\n  (:refer-clojure :exclude [defprotocol extend-type extend extend-p"
  },
  {
    "path": "test/ham_fisted/defprotocol_test/more_examples.clj",
    "chars": 256,
    "preview": "(ns ham-fisted.defprotocol-test.more-examples\n  (:require [ham-fisted.defprotocol :as hamf-defp]))\n\n(hamf-defp/defprotoc"
  },
  {
    "path": "test/ham_fisted/defprotocol_test/other_test.clj",
    "chars": 693,
    "preview": "(ns ham-fisted.defprotocol-test.other-test\n  (:refer-clojure :exclude [defprotocol extend-type extend extend-protocol sa"
  },
  {
    "path": "test/ham_fisted/defprotocol_test.clj",
    "chars": 15910,
    "preview": ";;   Copyright (c) Rich Hickey. All rights reserved.  The use and distribution terms for\n;;   this software are covered "
  },
  {
    "path": "test/ham_fisted/fjp_test.clj",
    "chars": 2480,
    "preview": "(ns ham-fisted.fjp-test\n  (:require [ham-fisted.api :as hamf]\n            [ham-fisted.fjp :as fjp]\n            [ham-fist"
  },
  {
    "path": "test/ham_fisted/hash_map_test.clj",
    "chars": 28937,
    "preview": "(ns ham-fisted.hash-map-test\n  (:require [clojure.test :refer [deftest is testing are]]\n            [clojure.set :as set"
  },
  {
    "path": "test/ham_fisted/hlet_test.clj",
    "chars": 980,
    "preview": "(ns ham-fisted.hlet-test\n  (:require [ham-fisted.api :as hamf]\n            [ham-fisted.primitive-invoke :as pi]\n        "
  },
  {
    "path": "test/ham_fisted/parallel_test.clj",
    "chars": 2190,
    "preview": "(ns ham-fisted.parallel-test\n  (:require [ham-fisted.api :as api]\n            [ham-fisted.reduce :as hamf-rf]\n          "
  },
  {
    "path": "test/ham_fisted/persistent_vector_test.clj",
    "chars": 16996,
    "preview": "(ns ham-fisted.persistent-vector-test\n  (:require [clojure.test :refer [deftest is testing are] :as test]\n            [c"
  },
  {
    "path": "test/ham_fisted/test_setup.clj",
    "chars": 521,
    "preview": "(ns ham-fisted.test-setup\n  \"Things we need to do in order to run tests with a smile\"\n  (:require [kaocha.hierarchy :as "
  },
  {
    "path": "test/ham_fisted/vec_like_test.clj",
    "chars": 3030,
    "preview": "(ns ham-fisted.vec-like-test\n  (:require [ham-fisted.api :as hamf]\n            [clojure.test :refer [deftest is] :as tes"
  },
  {
    "path": "tests.edn",
    "chars": 3269,
    "preview": "#kaocha/v1 {:capture-output?                 false\n            :kaocha/fail-fast?               false\n            :plugi"
  },
  {
    "path": "topics/Reductions.md",
    "chars": 18118,
    "preview": "# Reductions\n\nThe ham-fisted project extends the concept of Clojure's `reduce` in a few ways,\ntaking influence from java"
  }
]

About this extraction

This page contains the full source code of the cnuernber/ham-fisted GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 198 files (2.0 MB), approximately 630.3k tokens, and a symbol index with 2676 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!