Skip to content

Commit

Permalink
bgzf/gzi/index: Return virtual position from query
Browse files Browse the repository at this point in the history
  • Loading branch information
zaeleus committed Jan 16, 2025
1 parent 3d0fa23 commit 4d12e72
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 47 deletions.
11 changes: 1 addition & 10 deletions noodles-bgzf/src/async/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,8 @@ where
index: &gzi::Index,
pos: u64,
) -> io::Result<u64> {
let record = index.query(pos);

let cpos = record.0;
let upos = u16::try_from(pos - record.1)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

let virtual_position = VirtualPosition::try_from((cpos, upos))
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

let virtual_position = index.query(pos)?;
self.seek(virtual_position).await?;

Ok(pos)
}
}
Expand Down
33 changes: 20 additions & 13 deletions noodles-bgzf/src/gzi/index.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::io;

use crate::VirtualPosition;

/// A gzip index (GZI).
///
/// A gzip index holds compressed-uncompressed position pairs.
Expand All @@ -8,30 +12,33 @@
pub struct Index(Vec<(u64, u64)>);

impl Index {
/// Returns the record of the block that contains the given position.
/// Returns the virtual position at the given uncompressed position.
///
/// # Examples
///
/// ```
/// use noodles_bgzf::gzi;
/// use noodles_bgzf::{self as bgzf, gzi};
///
/// let index = gzi::Index::default();
/// assert_eq!(index.query(0), (0, 0));
/// assert_eq!(index.query(0)?, bgzf::VirtualPosition::default());
///
/// let index = gzi::Index::from(vec![(8, 21), (13, 55)]);
/// assert_eq!(index.query(0), (0, 0));
/// assert_eq!(index.query(13), (0, 0));
/// assert_eq!(index.query(34), (8, 21));
/// assert_eq!(index.query(89), (13, 55));
/// assert_eq!(index.query(0)?, bgzf::VirtualPosition::default());
/// assert_eq!(index.query(13)?, bgzf::VirtualPosition::try_from((0, 13))?);
/// assert_eq!(index.query(34)?, bgzf::VirtualPosition::try_from((8, 13))?);
/// assert_eq!(index.query(89)?, bgzf::VirtualPosition::try_from((13, 34))?);
/// Ok::<_, Box<dyn std::error::Error>>(())
/// ```
pub fn query(&self, pos: u64) -> (u64, u64) {
pub fn query(&self, pos: u64) -> io::Result<VirtualPosition> {
let i = self.0.partition_point(|r| r.1 <= pos);

if i == 0 {
(0, 0)
} else {
self.0[i - 1]
}
let (compressed_pos, uncompressed_pos) = if i == 0 { (0, 0) } else { self.0[i - 1] };

let block_data_pos = u16::try_from(pos - uncompressed_pos)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

VirtualPosition::try_from((compressed_pos, block_data_pos))
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
}
}

Expand Down
14 changes: 2 additions & 12 deletions noodles-bgzf/src/multithreaded_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,18 +339,8 @@ where
unimplemented!();
};

let record = index.query(pos);

let cpos = record.0;
self.get_mut().seek(SeekFrom::Start(cpos))?;
self.position = cpos;

self.read_block()?;

let upos = usize::try_from(pos - record.1)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
self.buffer.block.data_mut().set_position(upos);

let virtual_position = index.query(pos)?;
self.seek_to_virtual_position(virtual_position)?;
Ok(pos)
}
}
Expand Down
14 changes: 2 additions & 12 deletions noodles-bgzf/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,18 +203,8 @@ where
index: &gzi::Index,
pos: u64,
) -> io::Result<u64> {
let record = index.query(pos);

let cpos = record.0;
self.inner.seek(SeekFrom::Start(cpos))?;
self.position = cpos;

self.read_block()?;

let upos = usize::try_from(pos - record.1)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
self.block.data_mut().set_position(upos);

let virtual_position = index.query(pos)?;
self.seek(virtual_position)?;
Ok(pos)
}
}
Expand Down

0 comments on commit 4d12e72

Please sign in to comment.