Skip to content

Commit 16c209b

Browse files
committed
Introduce Borrow trait
The Borrow trait describes a type that can be borrowed into a reference type. It encapsulates the read-only parts of what formerly was Container. Similarly, we split PushIndexAs into this and BorrowIndexAs as a read-only variant. Signed-off-by: Moritz Hoffmann <antiguru@gmail.com>
1 parent b35d415 commit 16c209b

File tree

5 files changed

+259
-70
lines changed

5 files changed

+259
-70
lines changed

columnar_derive/src/lib.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -361,28 +361,30 @@ fn derive_struct(name: &syn::Ident, generics: &syn::Generics, data_struct: syn::
361361
type Container = #c_ident < #(<#types as ::columnar::Columnar>::Container ),* >;
362362
}
363363

364-
impl < #( #container_types: ::columnar::Container ),* > ::columnar::Container for #c_ident < #( #container_types ),* > {
365-
type Ref<'a> = #r_ident < #(<#container_types as ::columnar::Container>::Ref<'a>,)* > where #(#container_types: 'a,)*;
366-
type Borrowed<'a> = #c_ident < #(<#container_types as ::columnar::Container>::Borrowed<'a> ),* > where #(#container_types: 'a,)*;
364+
impl < #( #container_types: ::columnar::Borrow ),* > ::columnar::Borrow for #c_ident < #( #container_types ),* > {
365+
type Ref<'a> = #r_ident < #(<#container_types as ::columnar::Borrow>::Ref<'a>,)* > where #(#container_types: 'a,)*;
366+
type Borrowed<'a> = #c_ident < #(<#container_types as ::columnar::Borrow>::Borrowed<'a> ),* > where #(#container_types: 'a,)*;
367367
#[inline(always)]
368368
fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
369369
#c_ident {
370-
#( #names: <#container_types as ::columnar::Container>::borrow(&self.#names), )*
370+
#( #names: <#container_types as ::columnar::Borrow>::borrow(&self.#names), )*
371371
}
372372
}
373373
#[inline(always)]
374374
fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
375375
#c_ident {
376-
#( #names: <#container_types as ::columnar::Container>::reborrow(thing.#names), )*
376+
#( #names: <#container_types as ::columnar::Borrow>::reborrow(thing.#names), )*
377377
}
378378
}
379379
#[inline(always)]
380380
fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> {
381381
#r_ident {
382-
#( #names: <#container_types as ::columnar::Container>::reborrow_ref(thing.#names), )*
382+
#( #names: <#container_types as ::columnar::Borrow>::reborrow_ref(thing.#names), )*
383383
}
384384
}
385+
}
385386

387+
impl < #( #container_types: ::columnar::Container ),* > ::columnar::Container for #c_ident < #( #container_types ),* > {
386388
#[inline(always)]
387389
fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
388390
#( self.#names.extend_from_self(other.#names, range.clone()); )*
@@ -512,7 +514,7 @@ fn derive_unit_struct(name: &syn::Ident, _generics: &syn::Generics, vis: syn::Vi
512514
type Container = #c_ident;
513515
}
514516

515-
impl ::columnar::Container for #c_ident {
517+
impl ::columnar::Borrow for #c_ident {
516518
type Ref<'a> = #name;
517519
type Borrowed<'a> = #c_ident < &'a u64 >;
518520
#[inline(always)]
@@ -525,7 +527,9 @@ fn derive_unit_struct(name: &syn::Ident, _generics: &syn::Generics, vis: syn::Vi
525527
}
526528
#[inline(always)]
527529
fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
530+
}
528531

532+
impl ::columnar::Container for #c_ident {
529533
#[inline(always)]
530534
fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
531535
self.count += range.len() as u64;
@@ -970,7 +974,7 @@ fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::Dat
970974
let reborrow_ref = variants.iter().enumerate().zip(container_names.iter()).map(|((index, (variant, types)), cname)| {
971975
quote! {
972976
#r_ident::#variant(( potato )) => {
973-
#r_ident::#variant(( < (#cname) as ::columnar::Container >::reborrow_ref::<'b, 'a>( potato ) ))
977+
#r_ident::#variant(( < (#cname) as ::columnar::Borrow >::reborrow_ref::<'b, 'a>( potato ) ))
974978
},
975979
}
976980
}).collect::<Vec<_>>();
@@ -993,9 +997,9 @@ fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::Dat
993997
type Container = #c_ident < #(#container_types),* >;
994998
}
995999

996-
impl < #(#container_names : ::columnar::Container ),* > ::columnar::Container for #c_ident < #(#container_names),* > {
997-
type Ref<'a> = #r_ident < #( <#container_names as ::columnar::Container>::Ref<'a> ,)* > where Self: 'a, #(#container_names: 'a,)*;
998-
type Borrowed<'a> = #c_ident < #( < #container_names as ::columnar::Container >::Borrowed<'a>, )* &'a [u8], &'a [u64] > where #(#container_names: 'a,)*;
1000+
impl < #(#container_names : ::columnar::Borrow ),* > ::columnar::Borrow for #c_ident < #(#container_names),* > {
1001+
type Ref<'a> = #r_ident < #( <#container_names as ::columnar::Borrow>::Ref<'a> ,)* > where Self: 'a, #(#container_names: 'a,)*;
1002+
type Borrowed<'a> = #c_ident < #( < #container_names as ::columnar::Borrow >::Borrowed<'a>, )* &'a [u8], &'a [u64] > where #(#container_names: 'a,)*;
9991003
#[inline(always)]
10001004
fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
10011005
#c_ident {
@@ -1007,9 +1011,9 @@ fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::Dat
10071011
#[inline(always)]
10081012
fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
10091013
#c_ident {
1010-
#(#names: <#container_names as ::columnar::Container>::reborrow(thing.#names),)*
1011-
variant: <Vec<u8> as ::columnar::Container>::reborrow(thing.variant),
1012-
offset: <Vec<u64> as ::columnar::Container>::reborrow(thing.offset),
1014+
#(#names: <#container_names as ::columnar::Borrow>::reborrow(thing.#names),)*
1015+
variant: <Vec<u8> as ::columnar::Borrow>::reborrow(thing.variant),
1016+
offset: <Vec<u64> as ::columnar::Borrow>::reborrow(thing.offset),
10131017
}
10141018
}
10151019
#[inline(always)]
@@ -1018,7 +1022,9 @@ fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::Dat
10181022
#( #reborrow_ref )*
10191023
}
10201024
}
1025+
}
10211026

1027+
impl < #(#container_names : ::columnar::Container ),* > ::columnar::Container for #c_ident < #(#container_names),* > {
10221028
// TODO: implement `extend_from_self`.
10231029

10241030
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
@@ -1161,7 +1167,7 @@ fn derive_tags(name: &syn::Ident, _generics: &syn:: Generics, data_enum: syn::Da
11611167
type Container = #c_ident;
11621168
}
11631169

1164-
impl<CV: ::columnar::common::PushIndexAs<u8>> ::columnar::Container for #c_ident <CV> {
1170+
impl<CV: ::columnar::common::BorrowIndexAs<u8>> ::columnar::Borrow for #c_ident <CV> {
11651171
type Ref<'a> = #name;
11661172
type Borrowed<'a> = #c_ident < CV::Borrowed<'a> > where CV: 'a;
11671173
#[inline(always)]
@@ -1173,12 +1179,14 @@ fn derive_tags(name: &syn::Ident, _generics: &syn:: Generics, data_enum: syn::Da
11731179
#[inline(always)]
11741180
fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
11751181
#c_ident {
1176-
variant: <CV as ::columnar::Container>::reborrow(thing.variant),
1182+
variant: <CV as ::columnar::Borrow>::reborrow(thing.variant),
11771183
}
11781184
}
11791185
#[inline(always)]
11801186
fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
1187+
}
11811188

1189+
impl<CV: ::columnar::common::PushIndexAs<u8>> ::columnar::Container for #c_ident <CV> {
11821190
// TODO: implement `extend_from_self`.
11831191

11841192
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {

src/arc.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! Implementations of traits for `Arc<T>`
2+
use std::sync::Arc;
3+
4+
use crate::{Len, Borrow, HeapSize, AsBytes, FromBytes};
5+
6+
impl<T: Borrow> Borrow for Arc<T> {
7+
type Ref<'a> = T::Ref<'a> where T: 'a;
8+
type Borrowed<'a> = T::Borrowed<'a>;
9+
#[inline(always)] fn borrow<'a>(&'a self) -> Self::Borrowed<'a> { self.as_ref().borrow() }
10+
#[inline(always)] fn reborrow<'b, 'a: 'b>(item: Self::Borrowed<'a>) -> Self::Borrowed<'b> where Self: 'a { T::reborrow(item) }
11+
#[inline(always)] fn reborrow_ref<'b, 'a: 'b>(item: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { T::reborrow_ref(item) }
12+
}
13+
impl<T: Len> Len for Arc<T> {
14+
#[inline(always)] fn len(&self) -> usize { self.as_ref().len() }
15+
}
16+
impl<T: HeapSize> HeapSize for Arc<T> {
17+
fn heap_size(&self) -> (usize, usize) {
18+
let (l, c) = self.as_ref().heap_size();
19+
(l + std::mem::size_of::<Arc<T>>(), c + std::mem::size_of::<Arc<T>>())
20+
}
21+
}
22+
impl<'a, T: AsBytes<'a>> AsBytes<'a> for Arc<T> {
23+
#[inline(always)] fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> { self.as_ref().as_bytes() }
24+
}
25+
impl<'a, T: FromBytes<'a>> FromBytes<'a> for Arc<T> {
26+
#[inline(always)] fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self { Arc::new(T::from_bytes(bytes)) }
27+
}
28+
29+
#[cfg(test)]
30+
mod tests {
31+
use std::sync::Arc;
32+
use crate::{Borrow, Len, HeapSize, AsBytes, FromBytes};
33+
34+
#[test]
35+
fn test_borrow() {
36+
let x = Arc::new(vec![1, 2, 3]);
37+
let y: &[i32] = x.borrow();
38+
assert_eq!(y, &[1, 2, 3]);
39+
}
40+
41+
#[test]
42+
fn test_len() {
43+
let x = Arc::new(vec![1, 2, 3]);
44+
assert_eq!(x.len(), 3);
45+
}
46+
47+
#[test]
48+
fn test_heap_size() {
49+
let x = Arc::new(vec![1, 2, 3]);
50+
let (l, c) = x.heap_size();
51+
assert!(l > 0);
52+
assert!(c > 0);
53+
}
54+
55+
#[test]
56+
fn test_as_from_bytes() {
57+
let x = Arc::new(vec![1u8, 2, 3, 4, 5]);
58+
let bytes: Vec<_> = x.borrow().as_bytes().map(|(_, b)| b).collect();
59+
let y: Arc<&[u8]> = FromBytes::from_bytes(&mut bytes.into_iter());
60+
assert_eq!(*x, *y);
61+
}
62+
63+
#[test]
64+
fn test_borrow_tuple() {
65+
let x = (vec![4,5,6,7,], Arc::new(vec![1, 2, 3]));
66+
let y: (&[i32], &[i32]) = x.borrow();
67+
assert_eq!(y, ([4,5,6,7].as_ref(), [1, 2, 3].as_ref()));
68+
}
69+
}

0 commit comments

Comments
 (0)