(ns cljam.io.util.bgzf.gzi
(:require [cljam.util :as util])
(:import [java.nio ByteBuffer ByteOrder]
[java.nio.channels FileChannel FileChannel$MapMode]
[java.nio.file Paths OpenOption StandardOpenOption])) | |
(defn- read-full ^ByteBuffer [f]
(with-open [c (FileChannel/open
(Paths/get (.toURI (util/as-url f)))
(into-array OpenOption [StandardOpenOption/READ]))]
(.. c
(map FileChannel$MapMode/READ_ONLY 0 (.size c))
(order ByteOrder/LITTLE_ENDIAN)))) | |
(defn- parse-gzi [^ByteBuffer bb]
(let [n-entries (.getLong bb)]
(->> #(let [compressed (.getLong bb)
uncompressed (.getLong bb)]
[uncompressed compressed])
(repeatedly n-entries)
(into (sorted-map 0 0))))) | |
Reads a .gzi file and returns a sorted-map of uncompressed offsets to compressed offsets. | (defn read-gzi [f] (parse-gzi (read-full f))) |
Returns a virtual file offset for a given uncompressed offset. | (defn uncomp->comp
^long [gzi ^long uncompressed-offset]
(let [[u c] (first (rsubseq gzi <= uncompressed-offset))
diff (- uncompressed-offset (long u))]
(assert (<= 0 diff 0xffff))
(bit-or (bit-shift-left (long c) 16)
(bit-and diff 0xffff)))) |
Returns an uncompressed offset for a given virtual file offset | (defn comp->uncomp
^long [gzi ^long compressed-offset]
(let [off (unsigned-bit-shift-right compressed-offset 16)
uncompressed (->> gzi
rseq
(filter (fn [[_ c]] (= (long c) off)))
ffirst
long)]
(+ uncompressed (bit-and compressed-offset 0xffff)))) |