1395 lines
62 KiB
HTML
1395 lines
62 KiB
HTML
|
||||
|
|
<!DOCTYPE html>
|
|||
|
|
|
|||
|
|
<html class="no-js" lang="en">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="utf-8"/>
|
|||
|
|
<meta content="width=device-width,initial-scale=1" name="viewport"/>
|
|||
|
|
<link href="../../assets/images/favicon.png" rel="icon"/>
|
|||
|
|
<meta content="mkdocs-1.6.1, mkdocs-material-9.7.6" name="generator"/>
|
|||
|
|
<title>obicompactvec — Complete Reference - obikmer</title>
|
|||
|
|
<link href="../../assets/stylesheets/main.484c7ddc.min.css" rel="stylesheet"/>
|
|||
|
|
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
|||
|
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback" rel="stylesheet"/>
|
|||
|
|
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
|
|||
|
|
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
|||
|
|
</head>
|
|||
|
|
<body dir="ltr">
|
|||
|
|
<input autocomplete="off" class="md-toggle" data-md-toggle="drawer" id="__drawer" type="checkbox"/>
|
|||
|
|
<input autocomplete="off" class="md-toggle" data-md-toggle="search" id="__search" type="checkbox"/>
|
|||
|
|
<label class="md-overlay" for="__drawer"></label>
|
|||
|
|
<div data-md-component="skip">
|
|||
|
|
<a class="md-skip" href="#obicompactvec-complete-reference">
|
|||
|
|
Skip to content
|
|||
|
|
</a>
|
|||
|
|
</div>
|
|||
|
|
<div data-md-component="announce">
|
|||
|
|
</div>
|
|||
|
|
<header class="md-header md-header--shadow" data-md-component="header">
|
|||
|
|
<nav aria-label="Header" class="md-header__inner md-grid">
|
|||
|
|
<a aria-label="obikmer" class="md-header__button md-logo" data-md-component="logo" href="../.." title="obikmer">
|
|||
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"></path></svg>
|
|||
|
|
</a>
|
|||
|
|
<label class="md-header__button md-icon" for="__drawer">
|
|||
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"></path></svg>
|
|||
|
|
</label>
|
|||
|
|
<div class="md-header__title" data-md-component="header-title">
|
|||
|
|
<div class="md-header__ellipsis">
|
|||
|
|
<div class="md-header__topic">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
obikmer
|
|||
|
|
</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="md-header__topic" data-md-component="header-topic">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
obicompactvec — Complete Reference
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
|||
|
|
</nav>
|
|||
|
|
</header>
|
|||
|
|
<div class="md-container" data-md-component="container">
|
|||
|
|
<main class="md-main" data-md-component="main">
|
|||
|
|
<div class="md-main__inner md-grid">
|
|||
|
|
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation">
|
|||
|
|
<div class="md-sidebar__scrollwrap">
|
|||
|
|
<div class="md-sidebar__inner">
|
|||
|
|
<nav aria-label="Navigation" class="md-nav md-nav--primary" data-md-level="0">
|
|||
|
|
<label class="md-nav__title" for="__drawer">
|
|||
|
|
<a aria-label="obikmer" class="md-nav__button md-logo" data-md-component="logo" href="../.." title="obikmer">
|
|||
|
|
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"></path></svg>
|
|||
|
|
</a>
|
|||
|
|
obikmer
|
|||
|
|
</label>
|
|||
|
|
<ul class="md-nav__list" data-md-scrollfix="">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../..">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Home
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../installation/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Installation
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item md-nav__item--nested">
|
|||
|
|
<input class="md-nav__toggle md-toggle" id="__nav_3" type="checkbox"/>
|
|||
|
|
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Theory
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
<span class="md-nav__icon md-icon"></span>
|
|||
|
|
</label>
|
|||
|
|
<nav aria-expanded="false" aria-labelledby="__nav_3_label" class="md-nav" data-md-level="1">
|
|||
|
|
<label class="md-nav__title" for="__nav_3">
|
|||
|
|
<span class="md-nav__icon md-icon"></span>
|
|||
|
|
|
|||
|
|
|
|||
|
|
Theory
|
|||
|
|
|
|||
|
|
|
|||
|
|
</label>
|
|||
|
|
<ul class="md-nav__list" data-md-scrollfix="">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../kmers/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Kmers and super-kmers
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../theory/encoding/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
DNA encoding
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../theory/entropy/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Entropy filter
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../theory/minimizer/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Minimizer selection
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../theory/indexing/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Partitioning architecture
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../theory/evolutionary_distances/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Central-position SNP distance (discussion)
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item md-nav__item--nested">
|
|||
|
|
<input class="md-nav__toggle md-toggle" id="__nav_4" type="checkbox"/>
|
|||
|
|
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Implementation
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
<span class="md-nav__icon md-icon"></span>
|
|||
|
|
</label>
|
|||
|
|
<nav aria-expanded="false" aria-labelledby="__nav_4_label" class="md-nav" data-md-level="1">
|
|||
|
|
<label class="md-nav__title" for="__nav_4">
|
|||
|
|
<span class="md-nav__icon md-icon"></span>
|
|||
|
|
|
|||
|
|
|
|||
|
|
Implementation
|
|||
|
|
|
|||
|
|
|
|||
|
|
</label>
|
|||
|
|
<ul class="md-nav__list" data-md-scrollfix="">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../superkmer/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
SuperKmer
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../kmer/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Kmer
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../chunkreader/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Chunk reader
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../pipeline/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Construction pipeline
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../obipipeline/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
obipipeline library
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../storage/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
On-disk storage
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../mphf/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
MPHF selection
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../unitig_evidence/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Unitig evidence encoding
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../evidence_elimination/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Evidence elimination (discussion)
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../obilayeredmap/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
obilayeredmap crate
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../persistent_compact_int_vec/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
PersistentCompactIntVec
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../persistent_bit_vec/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
PersistentBitVec
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../merge/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Merge command
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../merge_parallelism/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Merge parallelism & memory
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../filtering/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Kmer filtering
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../select/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Select command
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../obitaxonomy/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
obitaxonomy crate
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item md-nav__item--nested">
|
|||
|
|
<input class="md-nav__toggle md-toggle" id="__nav_5" type="checkbox"/>
|
|||
|
|
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Architecture
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
<span class="md-nav__icon md-icon"></span>
|
|||
|
|
</label>
|
|||
|
|
<nav aria-expanded="false" aria-labelledby="__nav_5_label" class="md-nav" data-md-level="1">
|
|||
|
|
<label class="md-nav__title" for="__nav_5">
|
|||
|
|
<span class="md-nav__icon md-icon"></span>
|
|||
|
|
|
|||
|
|
|
|||
|
|
Architecture
|
|||
|
|
|
|||
|
|
|
|||
|
|
</label>
|
|||
|
|
<ul class="md-nav__list" data-md-scrollfix="">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../architecture/sequences/invariant/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Sequences
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../architecture/index_architecture/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Kmer index
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../architecture/siblings/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Sibling annex (discussion)
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../architecture/numa_worker_pools/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
NUMA-aware worker pools
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="../../architecture/numa_partition_runner/">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
|
|||
|
|
NUMA-aware partition runner
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc">
|
|||
|
|
<div class="md-sidebar__scrollwrap">
|
|||
|
|
<div class="md-sidebar__inner">
|
|||
|
|
<nav aria-label="Table of contents" class="md-nav md-nav--secondary">
|
|||
|
|
<label class="md-nav__title" for="__toc">
|
|||
|
|
<span class="md-nav__icon md-icon"></span>
|
|||
|
|
Table of contents
|
|||
|
|
</label>
|
|||
|
|
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix="">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#module-structure">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Module structure
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#compact-int-encoding">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Compact int encoding
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#view-types">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
View types
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
<nav aria-label="View types" class="md-nav">
|
|||
|
|
<ul class="md-nav__list">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#bitsliceviewa">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
BitSliceView<'a>
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#intsliceviewa">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
IntSliceView<'a>
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#concrete-types">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Concrete types
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
<nav aria-label="Concrete types" class="md-nav">
|
|||
|
|
<ul class="md-nav__list">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#persistentbitvec-persistentbitvecbuilder">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
PersistentBitVec / PersistentBitVecBuilder
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#persistentcompactintvec-persistentcompactintvecbuilder">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
PersistentCompactIntVec / PersistentCompactIntVecBuilder
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#matrix-types">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Matrix types
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#aggregation-traits-matrix-level">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Aggregation traits (matrix level)
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
<nav aria-label="Aggregation traits (matrix level)" class="md-nav">
|
|||
|
|
<ul class="md-nav__list">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#columnweights">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
ColumnWeights
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#countpartials">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
CountPartials
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#bitpartials">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
BitPartials
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#mash-distance">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Mash distance
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#temp-file-backed-types">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Temp-file-backed types
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
<nav aria-label="Temp-file-backed types" class="md-nav">
|
|||
|
|
<ul class="md-nav__list">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#lifecycle">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Lifecycle
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#tempcompactintvec-tempcompactintvecbuilder">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
TempCompactIntVec / TempCompactIntVecBuilder
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#tempbitvec-tempbitvecbuilder">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
TempBitVec / TempBitVecBuilder
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#filter-select-api">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Filter / Select API
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
<nav aria-label="Filter / Select API" class="md-nav">
|
|||
|
|
<ul class="md-nav__list">
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#colgroup">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
ColGroup
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#composition-axis">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
Composition axis
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#matrixgroupops">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
MatrixGroupOps
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#add_col_from-matrix-builder-integration">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
add_col_from — matrix builder integration
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
<li class="md-nav__item">
|
|||
|
|
<a class="md-nav__link" href="#mask_with">
|
|||
|
|
<span class="md-ellipsis">
|
|||
|
|
|
|||
|
|
mask_with
|
|||
|
|
|
|||
|
|
</span>
|
|||
|
|
</a>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</nav>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="md-content" data-md-component="content">
|
|||
|
|
<article class="md-content__inner md-typeset">
|
|||
|
|
<h1 id="obicompactvec-complete-reference">obicompactvec — Complete Reference</h1>
|
|||
|
|
<h2 id="module-structure">Module structure</h2>
|
|||
|
|
<div class="highlight"><pre><span></span><code>src/obicompactvec/src/
|
|||
|
|
lib.rs public re-exports
|
|||
|
|
views.rs BitSliceView<'a>, IntSliceView<'a> — zero-copy read views
|
|||
|
|
traits.rs ColumnWeights, CountPartials, BitPartials (matrix aggregation)
|
|||
|
|
bitvec.rs PersistentBitVec, PersistentBitVecBuilder, BitIter
|
|||
|
|
reader.rs PersistentCompactIntVec (read-only)
|
|||
|
|
builder.rs PersistentCompactIntVecBuilder (read-write)
|
|||
|
|
tempintvec.rs TempCompactIntVec, TempCompactIntVecBuilder (temp-file-backed)
|
|||
|
|
tempbitvec.rs TempBitVec, TempBitVecBuilder (temp-file-backed)
|
|||
|
|
bitmatrix.rs PersistentBitMatrix, PersistentBitMatrixBuilder
|
|||
|
|
intmatrix.rs PersistentCompactIntMatrix, PersistentCompactIntMatrixBuilder
|
|||
|
|
colgroup.rs ColGroup, MatrixGroupOps trait
|
|||
|
|
format.rs file format constants, encode/decode helpers
|
|||
|
|
layer_meta.rs LayerMeta (column metadata)
|
|||
|
|
meta.rs matrix metadata
|
|||
|
|
</code></pre></div>
|
|||
|
|
<pre class="mermaid"><code>graph TD
|
|||
|
|
views --> bitvec
|
|||
|
|
views --> builder
|
|||
|
|
views --> tempbitvec
|
|||
|
|
views --> tempintvec
|
|||
|
|
views --> bitmatrix
|
|||
|
|
views --> intmatrix
|
|||
|
|
format --> reader
|
|||
|
|
format --> builder
|
|||
|
|
reader --> intmatrix
|
|||
|
|
reader --> tempintvec
|
|||
|
|
builder --> intmatrix
|
|||
|
|
builder --> tempintvec
|
|||
|
|
bitvec --> tempbitvec
|
|||
|
|
bitvec --> bitmatrix
|
|||
|
|
tempintvec --> intmatrix
|
|||
|
|
tempintvec --> bitmatrix
|
|||
|
|
tempbitvec --> intmatrix
|
|||
|
|
tempbitvec --> bitmatrix
|
|||
|
|
colgroup --> intmatrix
|
|||
|
|
colgroup --> bitmatrix
|
|||
|
|
layer_meta --> bitmatrix
|
|||
|
|
layer_meta --> intmatrix
|
|||
|
|
meta --> bitmatrix
|
|||
|
|
meta --> intmatrix</code></pre>
|
|||
|
|
<hr/>
|
|||
|
|
<h2 id="compact-int-encoding">Compact int encoding</h2>
|
|||
|
|
<p>All integer vectors use the same two-tier encoding regardless of storage backend.</p>
|
|||
|
|
<p><strong>Primary array</strong> — one <code>u8</code> per slot:</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>Values <strong>0–254</strong> are stored directly. No overhead.</li>
|
|||
|
|
<li>Value <strong>255 is a sentinel</strong>: the slot's actual value is ≥ 255 and lives in the overflow store.</li>
|
|||
|
|
</ul>
|
|||
|
|
<p><strong>Overflow store</strong> — maps slot index to a <code>u32</code> value ≥ 255:</p>
|
|||
|
|
<ul>
|
|||
|
|
<li>In <code>PersistentCompactIntVecBuilder</code>: a <code>HashMap<usize, u32></code> in RAM.</li>
|
|||
|
|
<li>In <code>PersistentCompactIntVec</code> (reader): a sorted <code>[(slot: u64, value: u32)]</code> array in the mmap, with a sparse L1-resident index for binary search.</li>
|
|||
|
|
</ul>
|
|||
|
|
<pre class="mermaid"><code>flowchart LR
|
|||
|
|
slot --> P["primary[slot]: u8"]
|
|||
|
|
P -->|"< 255"| V["value = byte (0–254)"]
|
|||
|
|
P -->|"= 255 sentinel"| OV["overflow store"]
|
|||
|
|
OV -->|"Builder"| HM["HashMap&lt;usize, u32&gt;\nin RAM"]
|
|||
|
|
OV -->|"PersistentCompactIntVec"| SA["sorted [(slot,value)] in mmap\n+ sparse L1 index"]</code></pre>
|
|||
|
|
<p><strong>Key property — sentinel 255 = +∞ on <code>u8</code>:</strong></p>
|
|||
|
|
<ul>
|
|||
|
|
<li><code>min(a, 255) = a</code> for all <code>a ≤ 254</code> → correct when only one side is overflow</li>
|
|||
|
|
<li><code>max(a, 255) = 255</code> → correct sentinel when either side is overflow</li>
|
|||
|
|
<li>Only the <strong>both-overflow</strong> case requires reading actual values from the overflow store.</li>
|
|||
|
|
</ul>
|
|||
|
|
<p>In practice, k (overflow count) ≪ n (total slots). Observed genomic data: ~0.07% of kmer slots are in overflow.</p>
|
|||
|
|
<hr/>
|
|||
|
|
<h2 id="view-types">View types</h2>
|
|||
|
|
<p>The previous trait hierarchy (<code>BitSlice</code>, <code>BitSliceMut</code>, <code>IntSlice</code>, <code>IntSliceMut</code>) has been replaced by two concrete zero-copy view structs with inherent methods. Views are <strong><code>Copy</code></strong> — passing them is free. All read operations live on these two types.</p>
|
|||
|
|
<h3 id="bitsliceviewa"><code>BitSliceView<'a></code></h3>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="cp">#[derive(Clone, Copy)]</span>
|
|||
|
|
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">BitSliceView</span><span class="o"><'</span><span class="na">a</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">words</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="o">'</span><span class="na">a</span><span class="w"> </span><span class="p">[</span><span class="kt">u64</span><span class="p">],</span><span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="p">}</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p>Bit <code>i</code> is at <code>words[i >> 6]</code> bit <code>i & 63</code> (LSB-first). Padding bits in the last word are zero.</p>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>Method</th>
|
|||
|
|
<th>Cost</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>len()</code>, <code>is_empty()</code></td>
|
|||
|
|
<td>O(1)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>get(slot)</code></td>
|
|||
|
|
<td>O(1)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>count_ones()</code></td>
|
|||
|
|
<td>POPCNT per word, O(n/64)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>count_zeros()</code></td>
|
|||
|
|
<td><code>n − count_ones()</code>, O(n/64)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>iter() -> BitSliceIter<'a></code></td>
|
|||
|
|
<td>O(1) setup, O(n) iteration</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>partial_jaccard_dist(other: BitSliceView)</code></td>
|
|||
|
|
<td><code>(a&b).popcount</code>, <code>(a\|b).popcount</code> per word, O(n/64)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>jaccard_dist(other: BitSliceView)</code></td>
|
|||
|
|
<td>from partial, O(n/64)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>hamming_dist(other: BitSliceView)</code></td>
|
|||
|
|
<td><code>(a^b).popcount</code> per word, O(n/64)</td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<p><code>BitSliceIter<'a></code>: word-level scan; one word per 64 iterations.</p>
|
|||
|
|
<h3 id="intsliceviewa"><code>IntSliceView<'a></code></h3>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="cp">#[derive(Clone, Copy)]</span>
|
|||
|
|
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">IntSliceView</span><span class="o"><'</span><span class="na">a</span><span class="o">></span><span class="w"> </span><span class="p">{</span>
|
|||
|
|
<span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">primary</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="o">'</span><span class="na">a</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">],</span>
|
|||
|
|
<span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">overflow_raw</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="o">'</span><span class="na">a</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">],</span><span class="w"> </span><span class="c1">// sorted [(slot:u64, value:u32)] entries</span>
|
|||
|
|
<span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">n_overflow</span><span class="p">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span>
|
|||
|
|
<span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span>
|
|||
|
|
<span class="p">}</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><code>overflow_raw</code> contains <code>n_overflow</code> entries of <code>OVERFLOW_ENTRY_SIZE</code> bytes each, sorted by slot. The sort invariant is established at <code>close()</code>/<code>freeze()</code> time.</p>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>Method</th>
|
|||
|
|
<th>Cost</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>len()</code>, <code>is_empty()</code></td>
|
|||
|
|
<td>O(1)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>primary_bytes()</code></td>
|
|||
|
|
<td>O(1)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>overflow_entries() -> impl Iterator<(usize,u32)></code></td>
|
|||
|
|
<td>O(n_overflow) iteration</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>get(slot)</code></td>
|
|||
|
|
<td>O(1) primary; binary search O(log k) for overflow slots</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>iter() -> IntSliceViewIter<'a></code></td>
|
|||
|
|
<td>merge scan, O(n + k)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>sum()</code></td>
|
|||
|
|
<td>byte scan + overflow, O(n + k)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>count_nonzero()</code></td>
|
|||
|
|
<td>byte scan, O(n)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>Distance methods (<code>bray_dist</code>, <code>euclidean_dist</code>, <code>jaccard_dist</code>, …)</td>
|
|||
|
|
<td>O(n + k)</td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<p><code>IntSliceViewIter<'a></code>: merge scan using <code>overflow_pos</code> index. Requires sorted overflow — guaranteed by the construction lifecycle.</p>
|
|||
|
|
<p><strong>Builder <code>view()</code> vs reader <code>view()</code>:</strong> <code>PersistentCompactIntVecBuilder</code> stores overflow as an unsorted <code>HashMap</code>, not raw bytes. Its <code>view()</code> returns an <code>IntSliceView</code> with <code>overflow_raw = &[]</code> and <code>n_overflow = 0</code>. This is intentional — the view is primarily useful after <code>freeze()</code>. During building, callers that need overflow use <code>overflow_entries()</code> directly.</p>
|
|||
|
|
<hr/>
|
|||
|
|
<h2 id="concrete-types">Concrete types</h2>
|
|||
|
|
<pre class="mermaid"><code>classDiagram
|
|||
|
|
class BitSliceView {
|
|||
|
|
+words: &[u64]
|
|||
|
|
+n: usize
|
|||
|
|
+get(slot) bool
|
|||
|
|
+count_ones() u64
|
|||
|
|
+iter() BitSliceIter
|
|||
|
|
+jaccard_dist/hamming_dist(other: BitSliceView)
|
|||
|
|
}
|
|||
|
|
class IntSliceView {
|
|||
|
|
+primary: &[u8]
|
|||
|
|
+overflow_raw: &[u8]
|
|||
|
|
+n_overflow: usize
|
|||
|
|
+n: usize
|
|||
|
|
+get(slot) u32
|
|||
|
|
+iter() IntSliceViewIter
|
|||
|
|
+overflow_entries() Iterator
|
|||
|
|
+bray_dist/euclidean_dist/…(other: IntSliceView)
|
|||
|
|
}
|
|||
|
|
class PersistentBitVec {
|
|||
|
|
-mmap: Mmap
|
|||
|
|
-n: usize
|
|||
|
|
+view() BitSliceView
|
|||
|
|
+get(slot) bool
|
|||
|
|
+count_ones/zeros() u64
|
|||
|
|
+iter() BitIter
|
|||
|
|
+partial_jaccard_dist(&Self) (u64,u64)
|
|||
|
|
+jaccard_dist/hamming_dist(&Self) …
|
|||
|
|
}
|
|||
|
|
class PersistentBitVecBuilder {
|
|||
|
|
-mmap: MmapMut
|
|||
|
|
-n: usize
|
|||
|
|
+view() BitSliceView
|
|||
|
|
+set(slot, bool)
|
|||
|
|
+or/and/xor/not(BitSliceView)
|
|||
|
|
+copy_from(BitSliceView)
|
|||
|
|
+close() / finish() → PersistentBitVec
|
|||
|
|
}
|
|||
|
|
class PersistentCompactIntVec {
|
|||
|
|
-mmap: Mmap
|
|||
|
|
-n: usize
|
|||
|
|
-n_overflow: usize
|
|||
|
|
-step: usize
|
|||
|
|
-index: Vec~(usize,usize)~
|
|||
|
|
+view() IntSliceView
|
|||
|
|
+get(slot) u32
|
|||
|
|
+iter() Iter
|
|||
|
|
+sum/count_nonzero() u64
|
|||
|
|
+bray_dist/euclidean_dist/… (&Self)
|
|||
|
|
}
|
|||
|
|
class PersistentCompactIntVecBuilder {
|
|||
|
|
-mmap: MmapMut
|
|||
|
|
-n: usize
|
|||
|
|
-overflow: HashMap~usize,u32~
|
|||
|
|
+view() IntSliceView
|
|||
|
|
+set(slot, u32) / get(slot) u32
|
|||
|
|
+inc / inc_present / inc_present_fast
|
|||
|
|
+inc_predicate / inc_predicate_fast
|
|||
|
|
+add/min/max/diff/mask_with(…View)
|
|||
|
|
+primary_bytes/primary_bytes_mut()
|
|||
|
|
+close() / finish() → PersistentCompactIntVec
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PersistentBitVec --> BitSliceView : view()
|
|||
|
|
PersistentBitVecBuilder --> BitSliceView : view()
|
|||
|
|
PersistentCompactIntVec --> IntSliceView : view()
|
|||
|
|
PersistentCompactIntVecBuilder --> IntSliceView : view() (primary only)
|
|||
|
|
PersistentBitVecBuilder --> PersistentBitVec : close() then open()
|
|||
|
|
PersistentCompactIntVecBuilder --> PersistentCompactIntVec : close() then open()</code></pre>
|
|||
|
|
<h3 id="persistentbitvec-persistentbitvecbuilder"><code>PersistentBitVec</code> / <code>PersistentBitVecBuilder</code></h3>
|
|||
|
|
<p><code>PersistentBitVec</code> is the read-only type. <code>view()</code> returns a <code>BitSliceView<'_></code> over the mmap word array. Direct inherent methods delegate to the view: <code>count_ones()</code>, <code>count_zeros()</code>, <code>partial_jaccard_dist(&Self)</code>, <code>jaccard_dist(&Self)</code>, <code>hamming_dist(&Self)</code>.</p>
|
|||
|
|
<p><code>BitIter<'a></code> — exported iterator for <code>PersistentBitVec::iter()</code>:</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">BitIter</span><span class="o"><'</span><span class="na">a</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">words</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="o">'</span><span class="na">a</span><span class="w"> </span><span class="p">[</span><span class="kt">u64</span><span class="p">],</span><span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">slot</span><span class="p">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="n">n</span><span class="p">:</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="p">}</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><code>PersistentBitVecBuilder</code> is the read-write type. Mutation operations accept <code>BitSliceView<'_></code>:</p>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>Method</th>
|
|||
|
|
<th>Cost</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>set(slot, bool)</code></td>
|
|||
|
|
<td>O(1)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>view() -> BitSliceView<'_></code></td>
|
|||
|
|
<td>O(1)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>or/and/xor(BitSliceView)</code></td>
|
|||
|
|
<td>word-level, O(n/64), SIMD-friendly</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>not()</code></td>
|
|||
|
|
<td><code>w ^= u64::MAX</code> per word, re-masks last word</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>copy_from(BitSliceView)</code></td>
|
|||
|
|
<td><code>copy_from_slice</code></td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<h3 id="persistentcompactintvec-persistentcompactintvecbuilder"><code>PersistentCompactIntVec</code> / <code>PersistentCompactIntVecBuilder</code></h3>
|
|||
|
|
<p><code>PersistentCompactIntVec</code> is the read-only type. <code>view()</code> returns an <code>IntSliceView<'_></code> over the mmap primary and overflow arrays. Inherent <code>iter()</code> is a merge scan (<code>Iter</code> struct). Inherent <code>sum()</code> and <code>count_nonzero()</code> use fast byte-scan helpers.</p>
|
|||
|
|
<p><code>PersistentCompactIntVecBuilder</code> is the read-write type. Mutation methods on the builder fall into two categories:</p>
|
|||
|
|
<p><strong>Point mutations:</strong></p>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>Method</th>
|
|||
|
|
<th>Note</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>set(slot, u32)</code></td>
|
|||
|
|
<td>writes primary[slot] or 255+overflow</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>get(slot) -> u32</code></td>
|
|||
|
|
<td>reads primary byte or HashMap</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>inc(slot)</code></td>
|
|||
|
|
<td><code>get</code> + <code>set</code>, O(1)</td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<p><strong>Bulk computation methods</strong> — accept view arguments:</p>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>Method</th>
|
|||
|
|
<th>Semantics</th>
|
|||
|
|
<th>Overflow</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>inc_present(BitSliceView)</code></td>
|
|||
|
|
<td><code>+= 1</code> at each 1-bit</td>
|
|||
|
|
<td>via <code>inc</code>, safe for any group size</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>inc_present_fast(BitSliceView)</code></td>
|
|||
|
|
<td>same, raw u8 <code>+= 1</code></td>
|
|||
|
|
<td><code>debug_assert</code> no 255 reached</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>inc_predicate(IntSliceView, pred)</code></td>
|
|||
|
|
<td><code>+= 1</code> where <code>pred(col[s])</code></td>
|
|||
|
|
<td>two-pass, safe</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>inc_predicate_fast(IntSliceView, pred)</code></td>
|
|||
|
|
<td>same, raw u8</td>
|
|||
|
|
<td><code>debug_assert</code> no 255 reached</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>add(IntSliceView)</code></td>
|
|||
|
|
<td><code>self[s] += other[s]</code></td>
|
|||
|
|
<td>primary fast path + overflow fallback</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>min(IntSliceView)</code></td>
|
|||
|
|
<td>byte min + both-overflow fixup</td>
|
|||
|
|
<td>see algorithm below</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>max(IntSliceView)</code></td>
|
|||
|
|
<td>pre-pass + byte max</td>
|
|||
|
|
<td>see algorithm below</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>diff(IntSliceView)</code></td>
|
|||
|
|
<td>saturating sub</td>
|
|||
|
|
<td>self<255 hot path</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>mask_with(BitSliceView)</code></td>
|
|||
|
|
<td>zeros slots where mask bit = 0</td>
|
|||
|
|
<td>O(n_zeros)</td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<p><strong><code>inc_present_fast</code> / <code>inc_predicate_fast</code> invariant:</strong> caller guarantees no counter reaches 255 during the operation (group size < 255 for <code>inc_present_fast</code>, or chunk size < 255 for <code>inc_predicate_fast</code>). Violation is caught by <code>debug_assert</code> in dev builds.</p>
|
|||
|
|
<p><strong><code>min</code> algorithm:</strong></p>
|
|||
|
|
<p>Exploits 255 = +∞: byte-level min is correct unless both sides are overflow.</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code>snapshot self_ov: Vec<(slot,val)>
|
|||
|
|
snapshot other_ov: HashMap<slot,val>
|
|||
|
|
clear_overflow()
|
|||
|
|
Pass 1 — byte min, SIMD-vectorizable, O(n)
|
|||
|
|
Pass 2 — both-overflow fixup, O(k_self):
|
|||
|
|
for (slot, self_val) in self_ov:
|
|||
|
|
if slot ∈ other_ov: set(slot, min(self_val, other_ov[slot]))
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><strong><code>max</code> algorithm:</strong></p>
|
|||
|
|
<p>Cannot do byte max first — <code>max(255, b<255)=255</code> overwrites self's original overflow value. Pre-pass reads self's value at other's overflow slots before the byte pass.</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code>Pre-pass O(k_other): for (slot, other_val) in other.overflow_entries():
|
|||
|
|
set(slot, max(self.get(slot), other_val))
|
|||
|
|
Pass 1 — byte max, SIMD-vectorizable, O(n)
|
|||
|
|
</code></pre></div>
|
|||
|
|
<hr/>
|
|||
|
|
<h2 id="matrix-types">Matrix types</h2>
|
|||
|
|
<p>Four matrix types, two encodings × two formats:</p>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th></th>
|
|||
|
|
<th>Columnar format</th>
|
|||
|
|
<th>Packed format</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td><strong>Bit</strong></td>
|
|||
|
|
<td><code>PersistentBitMatrix</code> (Columnar variant)</td>
|
|||
|
|
<td><code>PersistentBitMatrix</code> (Packed variant)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><strong>Int</strong></td>
|
|||
|
|
<td><code>PersistentCompactIntMatrix</code> (Columnar variant)</td>
|
|||
|
|
<td><code>PersistentCompactIntMatrix</code> (Packed variant)</td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<p>Both matrix types are enums (<code>Columnar</code> / <code>Packed</code> / <code>Implicit</code> for bit) behind a transparent API. <code>col_view(c)</code> returns the appropriate view directly:</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// PersistentBitMatrix</span>
|
|||
|
|
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">col_view</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">c</span><span class="p">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">BitSliceView</span><span class="o"><'</span><span class="nb">_</span><span class="o">></span>
|
|||
|
|
|
|||
|
|
<span class="c1">// PersistentCompactIntMatrix</span>
|
|||
|
|
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">col_view</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">c</span><span class="p">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">IntSliceView</span><span class="o"><'</span><span class="nb">_</span><span class="o">></span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p>No wrapper enums (<code>BitColView</code>, <code>IntColView</code>): the caller receives a <code>Copy</code> view struct immediately usable with any view method or bulk builder method.</p>
|
|||
|
|
<p><code>pack_compact_int_matrix</code> and <code>pack_bit_matrix</code> convert columnar → packed format.</p>
|
|||
|
|
<hr/>
|
|||
|
|
<h2 id="aggregation-traits-matrix-level">Aggregation traits (matrix level)</h2>
|
|||
|
|
<h3 id="columnweights">ColumnWeights</h3>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">ColumnWeights</span><span class="p">:</span><span class="w"> </span><span class="nb">Send</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">Sync</span><span class="w"> </span><span class="p">{</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">col_weights</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">Array1</span><span class="o"><</span><span class="kt">u64</span><span class="o">></span><span class="p">;</span><span class="w"> </span><span class="c1">// sum per column</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">partial_kmer_counts</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">Array1</span><span class="o"><</span><span class="kt">u64</span><span class="o">></span><span class="p">;</span><span class="w"> </span><span class="c1">// default = col_weights()</span>
|
|||
|
|
<span class="p">}</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><code>partial_kmer_counts</code> is overridden for count matrices to return <code>count_nonzero</code> per column (distinct kmers) rather than total count.</p>
|
|||
|
|
<h3 id="countpartials">CountPartials</h3>
|
|||
|
|
<p>Abstract required methods: <code>partial_bray</code>, <code>partial_euclidean</code>, <code>partial_threshold_jaccard</code>, <code>partial_relfreq_bray</code>, <code>partial_relfreq_euclidean</code>, <code>partial_hellinger</code>.</p>
|
|||
|
|
<p><strong>Additivity rule:</strong> self-contained partials (<code>partial_bray</code>, <code>partial_euclidean</code>, <code>partial_threshold_jaccard</code>) can be element-wise summed across all <code>(partition, layer)</code> pairs. Normalised partials (<code>partial_relfreq_*</code>, <code>partial_hellinger</code>) require the <strong>global</strong> <code>col_weights</code> (accumulated across all layers and all partitions) as parameter.</p>
|
|||
|
|
<p><strong><code>partial_threshold_jaccard</code> returns <code>(inter, union)</code></strong> because <code>union[i,j]</code> depends on both columns simultaneously.</p>
|
|||
|
|
<p>Provided finalisations:</p>
|
|||
|
|
<table>
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>Finalisation</th>
|
|||
|
|
<th>Formula</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>bray_dist_matrix()</code></td>
|
|||
|
|
<td><code>1 − 2·partial_bray[i,j] / (w[i] + w[j])</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>euclidean_dist_matrix()</code></td>
|
|||
|
|
<td><code>√partial_euclidean[i,j]</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>threshold_jaccard_dist_matrix(t)</code></td>
|
|||
|
|
<td><code>1 − inter[i,j] / union[i,j]</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>relfreq_bray_dist_matrix()</code></td>
|
|||
|
|
<td><code>1 − partial_relfreq_bray[i,j]</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>relfreq_euclidean_dist_matrix()</code></td>
|
|||
|
|
<td><code>√partial_relfreq_euclidean[i,j]</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>hellinger_dist_matrix()</code></td>
|
|||
|
|
<td><code>√partial_hellinger[i,j] / √2</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>hellinger_euclidean_dist_matrix()</code></td>
|
|||
|
|
<td><code>√partial_hellinger[i,j]</code></td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>threshold_mash_dist_matrix(k, t)</code></td>
|
|||
|
|
<td>Mash distance, derived from <code>threshold_jaccard_dist_matrix(t)</code> — no separate partial</td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
<h3 id="bitpartials">BitPartials</h3>
|
|||
|
|
<p>Required: <code>partial_jaccard() -> (Array2<u64>, Array2<u64>)</code>, <code>partial_hamming() -> Array2<u64></code>. Both additive across layers and partitions.</p>
|
|||
|
|
<p>Provided finalisations also include <code>jaccard_dist_matrix()</code>, <code>hamming_dist_matrix()</code>, and <code>mash_dist_matrix(k)</code>.</p>
|
|||
|
|
<h3 id="mash-distance">Mash distance</h3>
|
|||
|
|
<p><code>mash_dist_matrix</code>/<code>threshold_mash_dist_matrix</code> add no new additive primitive: both are a pointwise transform of the existing Jaccard distance matrix, per the Mash mutation-rate estimator (Fan <em>et al.</em> 2015; Marbl Lab 2026)<sup id="fnref:Mash-distances-doc"><a class="footnote-ref" href="#fn:Mash-distances-doc">1</a></sup> <sup id="fnref:Fan2015-mash-formula"><a class="footnote-ref" href="#fn:Fan2015-mash-formula">2</a></sup>:</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code>D = -1/k · ln(2J / (1+J)), J = 1 - d_jaccard
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><code>J ≤ 0</code> (i.e. <code>d_jaccard ≥ 1</code>, no shared k-mers) maps to <code>D = 1</code> (maximal distance) rather than the <code>ln</code> singularity at <code>J = 0</code>.</p>
|
|||
|
|
<hr/>
|
|||
|
|
<h2 id="temp-file-backed-types">Temp-file-backed types</h2>
|
|||
|
|
<p><strong>All inter-function results use temp-file-backed types</strong> so the OS can page them out under memory pressure. This matters in practice: processing dozens of layers × hundreds of partitions in parallel would otherwise accumulate gigabytes of live anonymous memory.</p>
|
|||
|
|
<h3 id="lifecycle">Lifecycle</h3>
|
|||
|
|
<div class="highlight"><pre><span></span><code>TempCompactIntVecBuilder::new(n) → writable mmap in TempDir
|
|||
|
|
↓ (inc_present_fast / inc_predicate_fast / add / mask_with / …)
|
|||
|
|
.freeze() → TempCompactIntVec (read-only mmap + TempDir)
|
|||
|
|
↓ (optional)
|
|||
|
|
.make_persistent(path) → PersistentCompactIntVec (permanent file)
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p>Same pattern for <code>TempBitVecBuilder</code> → <code>TempBitVec</code> → <code>PersistentBitVec</code>.</p>
|
|||
|
|
<p><strong>Drop order</strong>: <code>TempCompactIntVec { vec: PersistentCompactIntVec, _temp: TempDir }</code> — Rust drops fields in declaration order. <code>vec</code> (mmap) released before <code>_temp</code> (directory deleted). No explicit <code>drop()</code> needed.</p>
|
|||
|
|
<h3 id="tempcompactintvec-tempcompactintvecbuilder">TempCompactIntVec / TempCompactIntVecBuilder</h3>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">TempCompactIntVec</span><span class="w"> </span><span class="p">{</span>
|
|||
|
|
<span class="w"> </span><span class="n">vec</span><span class="p">:</span><span class="w"> </span><span class="nc">PersistentCompactIntVec</span><span class="p">,</span>
|
|||
|
|
<span class="w"> </span><span class="n">_temp</span><span class="p">:</span><span class="w"> </span><span class="nc">TempDir</span><span class="p">,</span><span class="w"> </span><span class="c1">// dropped after vec</span>
|
|||
|
|
<span class="p">}</span>
|
|||
|
|
|
|||
|
|
<span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">TempCompactIntVecBuilder</span><span class="w"> </span><span class="p">{</span>
|
|||
|
|
<span class="w"> </span><span class="n">builder</span><span class="p">:</span><span class="w"> </span><span class="nc">PersistentCompactIntVecBuilder</span><span class="p">,</span>
|
|||
|
|
<span class="w"> </span><span class="n">temp</span><span class="p">:</span><span class="w"> </span><span class="nc">TempDir</span><span class="p">,</span>
|
|||
|
|
<span class="p">}</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><code>TempCompactIntVec</code>: read access via <code>get(slot)</code>, <code>sum()</code>, <code>iter()</code>, <code>view() -> IntSliceView<'_></code>.</p>
|
|||
|
|
<p><code>TempCompactIntVecBuilder</code>: full delegation to inner <code>PersistentCompactIntVecBuilder</code> — all bulk computation methods (<code>inc_present_fast</code>, <code>inc_predicate_fast</code>, <code>add</code>, <code>min</code>, <code>max</code>, <code>diff</code>, <code>mask_with</code>) are exposed as <code>pub(crate)</code>.</p>
|
|||
|
|
<h3 id="tempbitvec-tempbitvecbuilder">TempBitVec / TempBitVecBuilder</h3>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">TempBitVec</span><span class="w"> </span><span class="p">{</span>
|
|||
|
|
<span class="w"> </span><span class="n">vec</span><span class="p">:</span><span class="w"> </span><span class="nc">PersistentBitVec</span><span class="p">,</span>
|
|||
|
|
<span class="w"> </span><span class="n">_temp</span><span class="p">:</span><span class="w"> </span><span class="nc">TempDir</span><span class="p">,</span>
|
|||
|
|
<span class="p">}</span>
|
|||
|
|
|
|||
|
|
<span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">TempBitVecBuilder</span><span class="w"> </span><span class="p">{</span>
|
|||
|
|
<span class="w"> </span><span class="n">builder</span><span class="p">:</span><span class="w"> </span><span class="nc">PersistentBitVecBuilder</span><span class="p">,</span>
|
|||
|
|
<span class="w"> </span><span class="n">temp</span><span class="p">:</span><span class="w"> </span><span class="nc">TempDir</span><span class="p">,</span>
|
|||
|
|
<span class="p">}</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><code>TempBitVec</code>: read access via <code>get(slot)</code>, <code>count_ones()</code>, <code>view() -> BitSliceView<'_></code>, <code>iter()</code>.</p>
|
|||
|
|
<p><code>TempBitVecBuilder</code>: exposes <code>set(slot, bool)</code>, <code>or(BitSliceView)</code>, and:</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">or_where</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">col</span><span class="p">:</span><span class="w"> </span><span class="nc">IntSliceView</span><span class="o"><'</span><span class="nb">_</span><span class="o">></span><span class="p">,</span><span class="w"> </span><span class="n">pred</span><span class="p">:</span><span class="w"> </span><span class="nc">impl</span><span class="w"> </span><span class="nb">Fn</span><span class="p">(</span><span class="kt">u32</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="kt">bool</span><span class="p">)</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><code>or_where</code> — two passes, no intermediate allocation:</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code>Pass 1 — primary bytes, O(n):
|
|||
|
|
for slot in 0..n:
|
|||
|
|
b = col.primary_bytes()[slot]
|
|||
|
|
if b < 255 AND pred(b as u32): self.set(slot, true)
|
|||
|
|
|
|||
|
|
Pass 2 — overflow, O(k):
|
|||
|
|
for (slot, val) in col.overflow_entries():
|
|||
|
|
if pred(val): self.set(slot, true)
|
|||
|
|
</code></pre></div>
|
|||
|
|
<hr/>
|
|||
|
|
<h2 id="filter-select-api">Filter / Select API</h2>
|
|||
|
|
<h3 id="colgroup">ColGroup</h3>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">ColGroup</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">name</span><span class="p">:</span><span class="w"> </span><span class="nb">String</span><span class="p">,</span><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">indices</span><span class="p">:</span><span class="w"> </span><span class="nb">Vec</span><span class="o"><</span><span class="kt">usize</span><span class="o">></span><span class="w"> </span><span class="p">}</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p>Defined <strong>once at the index level</strong> from column metadata. Valid in all matrices of all layers and partitions — column structure is identical across the entire hierarchy; only rows (kmer slots) are partitioned.</p>
|
|||
|
|
<h3 id="composition-axis">Composition axis</h3>
|
|||
|
|
<ul>
|
|||
|
|
<li><strong>Across partitions</strong>: kmer space is partitioned → partial results <strong>concatenated</strong> (disjoint kmer ranges).</li>
|
|||
|
|
<li><strong>Across layers</strong>: same kmer space, different counts → partial results <strong>aggregated</strong> (add, OR, etc.).</li>
|
|||
|
|
</ul>
|
|||
|
|
<h3 id="matrixgroupops">MatrixGroupOps</h3>
|
|||
|
|
<p>Five required primitives + two default methods derived from them. All return temp-file-backed types.</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">MatrixGroupOps</span><span class="w"> </span><span class="p">{</span>
|
|||
|
|
<span class="w"> </span><span class="c1">// required</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">partial_group_presence_count</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">ColGroup</span><span class="p">,</span><span class="w"> </span><span class="n">threshold</span><span class="p">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">)</span>
|
|||
|
|
<span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="n">TempCompactIntVec</span><span class="o">></span><span class="p">;</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">partial_group_sum</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">ColGroup</span><span class="p">)</span>
|
|||
|
|
<span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="n">TempCompactIntVec</span><span class="o">></span><span class="p">;</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">partial_group_any</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">ColGroup</span><span class="p">,</span><span class="w"> </span><span class="n">threshold</span><span class="p">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">)</span>
|
|||
|
|
<span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="n">TempBitVec</span><span class="o">></span><span class="p">;</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">partial_group_min</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">ColGroup</span><span class="p">)</span>
|
|||
|
|
<span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="n">TempCompactIntVec</span><span class="o">></span><span class="p">;</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">partial_group_max</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">ColGroup</span><span class="p">)</span>
|
|||
|
|
<span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="n">TempCompactIntVec</span><span class="o">></span><span class="p">;</span>
|
|||
|
|
|
|||
|
|
<span class="w"> </span><span class="c1">// defaults derived from partial_group_presence_count</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">partial_group_all</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">ColGroup</span><span class="p">,</span><span class="w"> </span><span class="n">threshold</span><span class="p">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">)</span>
|
|||
|
|
<span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="n">TempBitVec</span><span class="o">></span><span class="p">;</span><span class="w"> </span><span class="c1">// slot=1 iff count == g.indices.len()</span>
|
|||
|
|
<span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">partial_group_none</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">ColGroup</span><span class="p">,</span><span class="w"> </span><span class="n">threshold</span><span class="p">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">)</span>
|
|||
|
|
<span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="n">TempBitVec</span><span class="o">></span><span class="p">;</span><span class="w"> </span><span class="c1">// slot=1 iff count == 0</span>
|
|||
|
|
<span class="p">}</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p>Implemented for both <code>PersistentCompactIntMatrix</code> and <code>PersistentBitMatrix</code>.</p>
|
|||
|
|
<p>For <strong>bit matrices</strong>: values are 0/1, so <code>partial_group_sum</code> = <code>partial_group_presence_count(g, 1)</code>; <code>partial_group_min</code> is AND (set first column then mask-with remaining); <code>partial_group_max</code> is OR via <code>partial_group_any</code> + <code>inc_present</code>.</p>
|
|||
|
|
<p><strong><code>partial_group_presence_count</code> — chunking for large groups:</strong></p>
|
|||
|
|
<p>When <code>g.indices.len() < 255</code>: per-slot counts stay within <code>u8</code> range. Use <code>inc_present_fast</code> (bit) or <code>inc_predicate_fast(col_view(c), |v| v >= threshold)</code> (int) — raw u8 increment, no overflow entry written.</p>
|
|||
|
|
<p>When <code>g.indices.len() ≥ 255</code>: process in chunks of 254 columns, accumulate via <code>.add(chunk_frozen.view())</code>.</p>
|
|||
|
|
<p><strong><code>partial_group_min</code> (int matrix)</strong>: copy first column via <code>.add(col_view(first))</code> (start from 0 ⇒ copy), then <code>.min(col_view(c))</code> for remaining.</p>
|
|||
|
|
<p><strong><code>partial_group_max</code> (int matrix)</strong>: <code>.max(col_view(c))</code> for all columns (start from 0 ⇒ first column acts as copy).</p>
|
|||
|
|
<p><strong><code>partial_group_any</code></strong> uses <code>or_where</code> on <code>TempBitVecBuilder</code> (two-pass: primary bytes then overflow entries).</p>
|
|||
|
|
<p><strong><code>partial_group_all</code> / <code>partial_group_none</code></strong> (default): call <code>partial_group_presence_count</code>, then iterate slots to produce the bit result. O(n) extra pass, not chunked.</p>
|
|||
|
|
<h3 id="add_col_from-matrix-builder-integration">add_col_from — matrix builder integration</h3>
|
|||
|
|
<p>Both matrix builders accept temp-file results directly:</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// PersistentBitMatrixBuilder</span>
|
|||
|
|
<span class="k">fn</span><span class="w"> </span><span class="nf">add_col_from</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">src</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">TempBitVec</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="p">()</span><span class="o">></span>
|
|||
|
|
<span class="k">fn</span><span class="w"> </span><span class="nf">add_col_from_int</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">src</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">TempCompactIntVec</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="p">()</span><span class="o">></span><span class="w"> </span><span class="c1">// nonzero → 1</span>
|
|||
|
|
|
|||
|
|
<span class="c1">// PersistentCompactIntMatrixBuilder</span>
|
|||
|
|
<span class="k">fn</span><span class="w"> </span><span class="nf">add_col_from</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">src</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">TempCompactIntVec</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="p">()</span><span class="o">></span>
|
|||
|
|
<span class="k">fn</span><span class="w"> </span><span class="nf">add_col_from_bit</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">src</span><span class="p">:</span><span class="w"> </span><span class="kp">&</span><span class="nc">TempBitVec</span><span class="p">)</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="nc">io</span><span class="p">::</span><span class="nb">Result</span><span class="o"><</span><span class="p">()</span><span class="o">></span><span class="w"> </span><span class="c1">// bit → 0/1 u32</span>
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p><code>add_col_from</code> copies the temp file to the matrix directory and increments <code>n_cols</code>; <code>close()</code> writes <code>meta.json</code> with the final column count. No separate <code>write_meta</code> step needed.</p>
|
|||
|
|
<h3 id="mask_with">mask_with</h3>
|
|||
|
|
<p>Direct method on <code>PersistentCompactIntVecBuilder</code> (and delegation via <code>TempCompactIntVecBuilder</code>). Zeros every slot where the corresponding mask bit is 0. Iterates only zero bits — O(n_zeros), O(1) when mask is all-ones.</p>
|
|||
|
|
<div class="highlight"><pre><span></span><code>for (w_idx, word) in mask.words():
|
|||
|
|
if word == u64::MAX: continue // skip all-ones words
|
|||
|
|
zeros = !word
|
|||
|
|
while zeros != 0:
|
|||
|
|
bit = trailing_zeros(zeros)
|
|||
|
|
s = w_idx * 64 + bit
|
|||
|
|
if primary[s] != 0: set(s, 0) // clears overflow entry too
|
|||
|
|
zeros &= zeros − 1
|
|||
|
|
</code></pre></div>
|
|||
|
|
<p>Terminal operation for Filter (retain only selected kmer slots in a count vector) and Select (positional selection without MPHF).</p>
|
|||
|
|
<div class="footnote">
|
|||
|
|
<hr/>
|
|||
|
|
<ol>
|
|||
|
|
<li id="fn:Mash-distances-doc">
|
|||
|
|
<p>Marbl Lab. (2026). <a href="https://mash.readthedocs.io/en/latest/distances.html">Mash distance</a>. <a class="footnote-backref" href="#fnref:Mash-distances-doc" title="Jump back to footnote 1 in the text">↩</a></p>
|
|||
|
|
</li>
|
|||
|
|
<li id="fn:Fan2015-mash-formula">
|
|||
|
|
<p>Fan, H., Ives, A.R., Surget-Groba, Y. & Cannon, C.H. (2015). <a href="https://doi.org/10.1186/s12864-015-1647-5">An assembly and alignment-free method of phylogeny reconstruction from next-generation sequencing data</a>. <em>BMC Genomics</em>, 16. <a class="footnote-backref" href="#fnref:Fan2015-mash-formula" title="Jump back to footnote 2 in the text">↩</a></p>
|
|||
|
|
</li>
|
|||
|
|
</ol>
|
|||
|
|
</div>
|
|||
|
|
</article>
|
|||
|
|
</div>
|
|||
|
|
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
|||
|
|
</div>
|
|||
|
|
</main>
|
|||
|
|
<footer class="md-footer">
|
|||
|
|
<div class="md-footer-meta md-typeset">
|
|||
|
|
<div class="md-footer-meta__inner md-grid">
|
|||
|
|
<div class="md-copyright">
|
|||
|
|
|
|||
|
|
|
|||
|
|
Made with
|
|||
|
|
<a href="https://squidfunk.github.io/mkdocs-material/" rel="noopener" target="_blank">
|
|||
|
|
Material for MkDocs
|
|||
|
|
</a>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</footer>
|
|||
|
|
</div>
|
|||
|
|
<div class="md-dialog" data-md-component="dialog">
|
|||
|
|
<div class="md-dialog__inner md-typeset"></div>
|
|||
|
|
</div>
|
|||
|
|
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": [], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
|
|||
|
|
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
|
|||
|
|
<script src="https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js"></script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|