Trait framework for row group indices, and initial implementation of range index.
Adding an overlap predicate for range indices.

Also, including some explanatory comments on the top-level traits and ranges.
Renamed RowGroupRangeIndex to just RangeIndex, and added a trait for writing an index.
Added a hash index on the unique values of a row group.

An example of an approrpiate use of this would be on the samples in a row group of genotypes.
Refactoring the materializeRecords method out into a separate object.

This is so that we can invoke the method to materialized records, from (e.g.) an Indexer,
without having to create ParquetPartition objects first.
Implemented RangeIndexGenerator, and a CLI command to call it.

RangeIndexGenerator produces the RangeIndexEntry values that can be written into a range index file.
It collapses consecutive ReferenceRegions, corresponding to the genotype rows, into a single ReferenceRegion
splitting only on boundaries between sites that are mroe than a threshold distance apart (10kb by default).

IndexFlatGenotype is a CLI command used to invoke the RangeIndexGenerator.