aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Bracco <href@random.sh>2021-11-12 18:19:13 +0100
committerJordan Bracco <href@random.sh>2021-11-12 18:19:13 +0100
commit7c2f9311bf166aab7300bc63d407d30ce1fe586b (patch)
tree909c9f90664383c8d4a1e7827ba675c55a21cf19
parentImprove API (diff)
treebitmap_nif: split nibbles/addrs in modulesHEADmain
-rw-r--r--native/treebitmap_nif/src/addrs.rs176
-rw-r--r--native/treebitmap_nif/src/lib.rs227
-rw-r--r--native/treebitmap_nif/src/nibbles.rs32
3 files changed, 218 insertions, 217 deletions
diff --git a/native/treebitmap_nif/src/addrs.rs b/native/treebitmap_nif/src/addrs.rs
new file mode 100644
index 0000000..68ddf16
--- /dev/null
+++ b/native/treebitmap_nif/src/addrs.rs
@@ -0,0 +1,176 @@
+use crate::nibbles::{Nibbles, NibblesV4, NibblesV6};
+use rustler::{NifRecord, NifUntaggedEnum};
+
+pub trait Maskable {
+ fn mask(self, masklen: u32) -> Self;
+}
+
+#[derive(Debug, NifRecord, Copy, Clone)]
+#[tag = "inet4"]
+pub struct TupleV4 {
+ pub a: u8,
+ pub b: u8,
+ pub c: u8,
+ pub d: u8,
+}
+
+impl TupleV4 {
+ pub fn from(num: u32) -> Self {
+ TupleV4 {
+ a: (num >> 24) as u8,
+ b: (num >> 16) as u8,
+ c: (num >> 8) as u8,
+ d: num as u8,
+ }
+ }
+
+ pub fn octets(&self) -> [u8; 4] {
+ [self.a, self.b, self.c, self.d]
+ }
+}
+
+impl Maskable for TupleV4 {
+ fn mask(self, masklen: u32) -> Self {
+ debug_assert!(masklen <= 32);
+ let ip = u32::from(self);
+ let masked = match masklen {
+ 0 => 0,
+ n => ip & (!0 << (32 - n)),
+ };
+ TupleV4::from(masked)
+ }
+}
+
+impl ::std::convert::From<TupleV4> for Nibbles {
+ fn from(a: TupleV4) -> Nibbles {
+ let mut ret: [u8; 8] = [0; 8];
+ let bytes: [u8; 4] = a.octets();
+ for (i, byte) in bytes.iter().enumerate() {
+ ret[i * 2] = byte >> 4;
+ ret[i * 2 + 1] = byte & 0xf;
+ }
+ Nibbles::V4(NibblesV4 { n: ret })
+ }
+}
+
+impl ::std::convert::From<TupleV4> for u32 {
+ fn from(a: TupleV4) -> u32 {
+ (a.a as u32) << 24 | (a.b as u32) << 16 | (a.c as u32) << 8 | (a.d as u32)
+ }
+}
+
+#[derive(Debug, NifRecord, Copy, Clone)]
+#[tag = "inet6"]
+pub struct TupleV6 {
+ pub a1: u16,
+ pub a2: u16,
+ pub a3: u16,
+ pub a4: u16,
+ pub a5: u16,
+ pub a6: u16,
+ pub a7: u16,
+ pub a8: u16,
+}
+
+impl TupleV6 {
+ #[allow(clippy::too_many_arguments)]
+ fn new(a1: u16, a2: u16, a3: u16, a4: u16, a5: u16, a6: u16, a7: u16, a8: u16) -> Self {
+ TupleV6 {
+ a1,
+ a2,
+ a3,
+ a4,
+ a5,
+ a6,
+ a7,
+ a8,
+ }
+ }
+
+ fn octets(&self) -> [u8; 16] {
+ [
+ (self.a1 >> 8) as u8,
+ self.a1 as u8,
+ (self.a2 >> 8) as u8,
+ self.a2 as u8,
+ (self.a3 >> 8) as u8,
+ self.a3 as u8,
+ (self.a4 >> 8) as u8,
+ self.a4 as u8,
+ (self.a5 >> 8) as u8,
+ self.a5 as u8,
+ (self.a6 >> 8) as u8,
+ self.a6 as u8,
+ (self.a7 >> 8) as u8,
+ self.a7 as u8,
+ (self.a8 >> 8) as u8,
+ self.a8 as u8,
+ ]
+ }
+
+ fn segments(&self) -> [u16; 8] {
+ let bytes = self.octets();
+ [
+ (bytes[0] as u16) << 8 | (bytes[1] as u16),
+ (bytes[2] as u16) << 8 | (bytes[3] as u16),
+ (bytes[4] as u16) << 8 | (bytes[5] as u16),
+ (bytes[6] as u16) << 8 | (bytes[7] as u16),
+ (bytes[8] as u16) << 8 | (bytes[9] as u16),
+ (bytes[10] as u16) << 8 | (bytes[11] as u16),
+ (bytes[12] as u16) << 8 | (bytes[13] as u16),
+ (bytes[14] as u16) << 8 | (bytes[15] as u16),
+ ]
+ }
+}
+
+impl Maskable for TupleV6 {
+ fn mask(self, masklen: u32) -> Self {
+ debug_assert!(masklen <= 128);
+ let mut ret = self.segments();
+ for i in ((masklen + 15) / 16)..8 {
+ ret[i as usize] = 0;
+ }
+ if masklen % 16 != 0 {
+ ret[masklen as usize / 16] &= !0 << (16 - (masklen % 16));
+ }
+ Self::new(
+ ret[0], ret[1], ret[2], ret[3], ret[4], ret[5], ret[6], ret[7],
+ )
+ }
+}
+
+impl ::std::convert::From<TupleV6> for Nibbles {
+ fn from(a: TupleV6) -> Nibbles {
+ let mut ret: [u8; 32] = [0; 32];
+ let bytes = a.octets();
+ for (i, byte) in bytes.iter().enumerate() {
+ ret[i * 2] = byte >> 4;
+ ret[i * 2 + 1] = byte & 0xf;
+ }
+ Nibbles::V6(NibblesV6 { n: ret })
+ }
+}
+
+#[derive(NifUntaggedEnum, Copy, Clone)]
+pub enum AddrTuple {
+ V4(TupleV4),
+ V6(TupleV6),
+}
+
+impl Maskable for AddrTuple {
+ fn mask(self, masklen: u32) -> Self {
+ match self {
+ AddrTuple::V4(tuple_v4) => AddrTuple::V4(tuple_v4.mask(masklen)),
+ AddrTuple::V6(tuple_v6) => AddrTuple::V6(tuple_v6.mask(masklen)),
+ }
+ }
+}
+
+impl ::std::convert::From<AddrTuple> for Nibbles {
+ fn from(a: AddrTuple) -> Nibbles {
+ match a {
+ AddrTuple::V4(v4) => Nibbles::from(v4),
+ AddrTuple::V6(v6) => Nibbles::from(v6),
+ }
+ }
+}
diff --git a/native/treebitmap_nif/src/lib.rs b/native/treebitmap_nif/src/lib.rs
index bde5e66..77d539a 100644
--- a/native/treebitmap_nif/src/lib.rs
+++ b/native/treebitmap_nif/src/lib.rs
@@ -1,229 +1,22 @@
-use rustler::{
- resource::ResourceArc, types::tuple::make_tuple, Encoder, Env, NifRecord, NifResult,
- NifUntaggedEnum, Term,
-};
-use std::sync::Mutex;
-
+mod addrs;
+mod nibbles;
mod tree_bitmap;
-use tree_bitmap::TreeBitmap;
-struct TableResource {
- pub tree: Mutex<TreeBitmap<u32>>,
-}
+use addrs::{AddrTuple, Maskable};
+use nibbles::Nibbles;
+use rustler::{resource::ResourceArc, types::tuple::make_tuple, Encoder, Env, NifResult, Term};
+use std::sync::Mutex;
+use tree_bitmap::TreeBitmap;
mod atoms {
rustler::atoms! {
ok,
- nil,
- error
- }
-}
-
-trait Maskable {
- fn mask(self, masklen: u32) -> Self;
-}
-
-struct NibblesV4 {
- pub n: [u8; 8],
-}
-struct NibblesV6 {
- pub n: [u8; 32],
-}
-
-enum Nibbles {
- V4(NibblesV4),
- V6(NibblesV6),
-}
-
-impl AsRef<[u8]> for Nibbles {
- fn as_ref(&self) -> &[u8] {
- match self {
- Nibbles::V4(nib4) => nib4.as_ref(),
- Nibbles::V6(nib6) => nib6.as_ref(),
- }
- }
-}
-
-impl AsRef<[u8]> for NibblesV4 {
- fn as_ref(&self) -> &[u8] {
- &self.n
- }
-}
-
-impl AsRef<[u8]> for NibblesV6 {
- fn as_ref(&self) -> &[u8] {
- &self.n
- }
-}
-
-#[derive(NifUntaggedEnum, Copy, Clone)]
-enum AddrTuple {
- V4(TupleV4),
- V6(TupleV6),
-}
-
-impl Maskable for AddrTuple {
- fn mask(self, masklen: u32) -> Self {
- match self {
- AddrTuple::V4(tuple_v4) => AddrTuple::V4(tuple_v4.mask(masklen)),
- AddrTuple::V6(tuple_v6) => AddrTuple::V6(tuple_v6.mask(masklen)),
- }
- }
-}
-
-#[derive(Debug, NifRecord, Copy, Clone)]
-#[tag = "inet4"]
-struct TupleV4 {
- pub a: u8,
- pub b: u8,
- pub c: u8,
- pub d: u8,
-}
-
-impl TupleV4 {
- pub fn from(num: u32) -> Self {
- TupleV4 {
- a: (num >> 24) as u8,
- b: (num >> 16) as u8,
- c: (num >> 8) as u8,
- d: num as u8,
- }
- }
-
- pub fn octets(&self) -> [u8; 4] {
- [self.a, self.b, self.c, self.d]
- }
-}
-
-impl Maskable for TupleV4 {
- fn mask(self, masklen: u32) -> Self {
- debug_assert!(masklen <= 32);
- let ip = u32::from(self);
- let masked = match masklen {
- 0 => 0,
- n => ip & (!0 << (32 - n)),
- };
- TupleV4::from(masked)
- }
-}
-
-impl ::std::convert::From<AddrTuple> for Nibbles {
- fn from(a: AddrTuple) -> Nibbles {
- match a {
- AddrTuple::V4(v4) => Nibbles::from(v4),
- AddrTuple::V6(v6) => Nibbles::from(v6),
- }
- }
-}
-
-impl ::std::convert::From<TupleV4> for Nibbles {
- fn from(a: TupleV4) -> Nibbles {
- let mut ret: [u8; 8] = [0; 8];
- let bytes: [u8; 4] = a.octets();
- for (i, byte) in bytes.iter().enumerate() {
- ret[i * 2] = byte >> 4;
- ret[i * 2 + 1] = byte & 0xf;
- }
- Nibbles::V4(NibblesV4 { n: ret })
- }
-}
-
-impl ::std::convert::From<TupleV4> for u32 {
- fn from(a: TupleV4) -> u32 {
- (a.a as u32) << 24 | (a.b as u32) << 16 | (a.c as u32) << 8 | (a.d as u32)
+ nil
}
}
-#[derive(Debug, NifRecord, Copy, Clone)]
-#[tag = "inet6"]
-struct TupleV6 {
- pub a1: u16,
- pub a2: u16,
- pub a3: u16,
- pub a4: u16,
- pub a5: u16,
- pub a6: u16,
- pub a7: u16,
- pub a8: u16,
-}
-
-impl TupleV6 {
- #[allow(clippy::too_many_arguments)]
- fn new(a1: u16, a2: u16, a3: u16, a4: u16, a5: u16, a6: u16, a7: u16, a8: u16) -> Self {
- TupleV6 {
- a1,
- a2,
- a3,
- a4,
- a5,
- a6,
- a7,
- a8,
- }
- }
-
- fn octets(&self) -> [u8; 16] {
- [
- (self.a1 >> 8) as u8,
- self.a1 as u8,
- (self.a2 >> 8) as u8,
- self.a2 as u8,
- (self.a3 >> 8) as u8,
- self.a3 as u8,
- (self.a4 >> 8) as u8,
- self.a4 as u8,
- (self.a5 >> 8) as u8,
- self.a5 as u8,
- (self.a6 >> 8) as u8,
- self.a6 as u8,
- (self.a7 >> 8) as u8,
- self.a7 as u8,
- (self.a8 >> 8) as u8,
- self.a8 as u8,
- ]
- }
-
- fn segments(&self) -> [u16; 8] {
- let bytes = self.octets();
- [
- (bytes[0] as u16) << 8 | (bytes[1] as u16),
- (bytes[2] as u16) << 8 | (bytes[3] as u16),
- (bytes[4] as u16) << 8 | (bytes[5] as u16),
- (bytes[6] as u16) << 8 | (bytes[7] as u16),
- (bytes[8] as u16) << 8 | (bytes[9] as u16),
- (bytes[10] as u16) << 8 | (bytes[11] as u16),
- (bytes[12] as u16) << 8 | (bytes[13] as u16),
- (bytes[14] as u16) << 8 | (bytes[15] as u16),
- ]
- }
-}
-
-impl Maskable for TupleV6 {
- fn mask(self, masklen: u32) -> Self {
- debug_assert!(masklen <= 128);
- let mut ret = self.segments();
- for i in ((masklen + 15) / 16)..8 {
- ret[i as usize] = 0;
- }
- if masklen % 16 != 0 {
- ret[masklen as usize / 16] &= !0 << (16 - (masklen % 16));
- }
- Self::new(
- ret[0], ret[1], ret[2], ret[3], ret[4], ret[5], ret[6], ret[7],
- )
- }
-}
-
-impl ::std::convert::From<TupleV6> for Nibbles {
- fn from(a: TupleV6) -> Nibbles {
- let mut ret: [u8; 32] = [0; 32];
- let bytes = a.octets();
- for (i, byte) in bytes.iter().enumerate() {
- ret[i * 2] = byte >> 4;
- ret[i * 2 + 1] = byte & 0xf;
- }
- Nibbles::V6(NibblesV6 { n: ret })
- }
+struct TableResource {
+ pub tree: Mutex<TreeBitmap<u32>>,
}
#[rustler::nif]
diff --git a/native/treebitmap_nif/src/nibbles.rs b/native/treebitmap_nif/src/nibbles.rs
new file mode 100644
index 0000000..ca1939b
--- /dev/null
+++ b/native/treebitmap_nif/src/nibbles.rs
@@ -0,0 +1,32 @@
+pub struct NibblesV4 {
+ pub n: [u8; 8],
+}
+pub struct NibblesV6 {
+ pub n: [u8; 32],
+}
+
+pub enum Nibbles {
+ V4(NibblesV4),
+ V6(NibblesV6),
+}
+
+impl AsRef<[u8]> for Nibbles {
+ fn as_ref(&self) -> &[u8] {
+ match self {
+ Nibbles::V4(nib4) => nib4.as_ref(),
+ Nibbles::V6(nib6) => nib6.as_ref(),
+ }
+ }
+}
+
+impl AsRef<[u8]> for NibblesV4 {
+ fn as_ref(&self) -> &[u8] {
+ &self.n
+ }
+}
+
+impl AsRef<[u8]> for NibblesV6 {
+ fn as_ref(&self) -> &[u8] {
+ &self.n
+ }
+}