Skip to content

Commit 690d3e7

Browse files
Roderick Boveeboydgreenfield
authored andcommitted
Bump to version 0.3 and clean up API/fix issues
- support read-only mmaps - make range u128 by default and remove `u128` feature - provide default implemetations of get/set_range - fix rank/select and provide default implementations - implement BitVector for u8 to u128 and for Vec<u8>/&[u8] - include combinatorial functions from downstream (choose and rank/unrank bit permutations; note different type of rank)
1 parent 10fd3d0 commit 690d3e7

File tree

8 files changed

+540
-296
lines changed

8 files changed

+540
-296
lines changed

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
[package]
22
name = "mmap-bitvec"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
authors = ["Roderick Bovee <roderick@onecodex.com>"]
55

66
[dependencies]
77
memmap = "0.6.2"
88
murmurhash3 = "0.0.5"
99

1010
[features]
11-
u128 = []
1211
backward_bytes = []
1312

1413
[dev-dependencies]

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2017 One Codex
3+
Copyright (c) Reference Genomics, Inc.
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

src/bin/test_get_range.rs

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/bin/test_get_range_fast.rs

Lines changed: 0 additions & 93 deletions
This file was deleted.

src/bitvec.rs

Lines changed: 125 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,132 @@
11
use std::ops::Range;
22

3-
#[cfg(not(feature = "u128"))]
4-
pub type BitVecSlice = u64;
5-
#[cfg(not(feature = "u128"))]
6-
pub const BIT_VEC_SLICE_SIZE: u8 = 64;
7-
#[cfg(feature = "u128")]
8-
pub type BitVecSlice = u128;
9-
#[cfg(feature = "u128")]
10-
pub const BIT_VEC_SLICE_SIZE: u8 = 128;
11-
123
pub trait BitVector {
13-
fn size(&self) -> usize;
144
fn get(&self, i: usize) -> bool;
15-
fn get_range(&self, r: Range<usize>) -> BitVecSlice;
165
fn set(&mut self, i: usize, x: bool);
17-
fn set_range(&mut self, r: Range<usize>, x: BitVecSlice);
18-
fn clear_range(&mut self, r: Range<usize>);
19-
fn rank(&self, r: Range<usize>) -> usize;
20-
fn select(&self, n: usize, start: usize) -> Option<usize>;
6+
fn size(&self) -> usize;
7+
8+
fn rank(&self, r: Range<usize>) -> usize {
9+
r.fold(0, |a, x| a + if self.get(x) { 1 } else { 0 })
10+
}
11+
12+
fn select(&self, n: usize, start: usize) -> Option<usize> {
13+
let mut bits_left = n;
14+
15+
for i in start..self.size() {
16+
if self.get(i) {
17+
bits_left -= 1;
18+
}
19+
20+
if bits_left == 0 {
21+
return Some(i);
22+
}
23+
}
24+
None
25+
}
26+
27+
fn get_range(&self, r: Range<usize>) -> u128 {
28+
if r.end - r.start > 128usize {
29+
panic!("Range too large (>128)")
30+
} else if r.end > self.size() {
31+
panic!("Range ends outside of BitVec")
32+
}
33+
34+
let mut bvs = 0;
35+
let mut bit_pos = 127;
36+
for i in r {
37+
if self.get(i) {
38+
bvs += 1 << bit_pos;
39+
};
40+
bit_pos -= 1;
41+
}
42+
bvs
43+
}
44+
45+
fn set_range(&mut self, r: Range<usize>, x: u128) {
46+
let mut cur = x;
47+
for i in r.rev() {
48+
self.set(i, cur & 1 == 1);
49+
cur >>= 1;
50+
}
51+
}
52+
53+
fn clear_range(&mut self, r: Range<usize>) {
54+
for i in r.rev() {
55+
self.set(i, false);
56+
}
57+
}
58+
}
59+
60+
macro_rules! impl_bitvector {
61+
( $type:ty, $type_size:expr ) => {
62+
impl BitVector for $type {
63+
fn get(&self, i: usize) -> bool {
64+
if i > $type_size - 1 {
65+
panic!("Invalid bit vector index");
66+
}
67+
(self & 1 << ($type_size - i)) > 0
68+
}
69+
70+
fn set(&mut self, i: usize, x: bool) {
71+
if x {
72+
self.clone_from(&(*self | (1 << ($type_size - i))));
73+
} else {
74+
self.clone_from(&(*self & !(1 << ($type_size - i))));
75+
}
76+
}
77+
78+
fn size(&self) -> usize {
79+
$type_size
80+
}
81+
}
82+
};
83+
}
84+
85+
impl_bitvector!(u8, 8);
86+
impl_bitvector!(u16, 16);
87+
impl_bitvector!(u32, 32);
88+
impl_bitvector!(u64, 64);
89+
impl_bitvector!(u128, 128);
90+
91+
impl BitVector for &[u8] {
92+
fn get(&self, i: usize) -> bool {
93+
if i / 8 >= self.len() {
94+
panic!("Invalid bit vector index");
95+
}
96+
self[i / 8] >> (8 - i % 8) & 1 == 1
97+
}
98+
99+
fn set(&mut self, _: usize, _: bool) {
100+
panic!("Can not set bits on a non-mut slice");
101+
}
102+
103+
fn size(&self) -> usize {
104+
self.len() / 8
105+
}
106+
}
107+
108+
impl BitVector for Vec<u8> {
109+
fn get(&self, i: usize) -> bool {
110+
if i / 8 >= self.len() {
111+
panic!("Invalid bit vector index");
112+
}
113+
self[i / 8] >> (8 - i % 8) & 1 == 1
114+
}
115+
116+
fn set(&mut self, i: usize, x: bool) {
117+
if i / 8 >= self.len() {
118+
panic!("Invalid bit vector index");
119+
}
120+
if x {
121+
self[i / 8] |= 1 << (8 - i);
122+
} else {
123+
self[i / 8] &= !(1 << (8 - i));
124+
}
125+
}
126+
127+
fn size(&self) -> usize {
128+
self.len() / 8
129+
}
21130
}
22131

23-
// TODO: impl for `std::collections::BitVec`?
132+
// TODO: impl for `bv::BitVec` and `bit-vec::BitVec`?

0 commit comments

Comments
 (0)