Skip to content

Commit

Permalink
refactor(query): use new hashtable in hash join
Browse files Browse the repository at this point in the history
  • Loading branch information
usamoi committed Oct 27, 2022
1 parent 9a3198a commit 4308477
Show file tree
Hide file tree
Showing 15 changed files with 374 additions and 93 deletions.
61 changes: 61 additions & 0 deletions src/common/hashtable/src/hashtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use super::table0::Entry;
use super::table0::Table0;
use super::table0::Table0Iter;
use super::table0::Table0IterMut;
use super::traits::HashtableLike;
use super::traits::Keyable;
use super::utils::ZeroEntry;

Expand Down Expand Up @@ -232,3 +233,63 @@ where K: Keyable
self.inner.next()
}
}

impl<K, V, A> HashtableLike for Hashtable<K, V, A>
where
K: Keyable,
A: Allocator + Clone + 'static,
{
type Key = K;
type KeyRef<'a> = K where K:'a;
type Value = V;

type EntryRef<'a> = &'a Entry<K, V> where Self:'a, K:'a, V: 'a;
type EntryMutRef<'a> = &'a mut Entry<K, V> where Self:'a, K:'a, V: 'a;

type Iterator<'a> = HashtableIter<'a, K, V> where Self:'a, K:'a, V: 'a;
type IteratorMut<'a> = HashtableIterMut<'a, K, V> where Self:'a, K:'a, V: 'a;

fn entry<'a>(&self, key_ref: Self::KeyRef<'a>) -> Option<Self::EntryRef<'_>>
where K: 'a {
self.entry(&key_ref)
}
fn entry_mut<'a>(&mut self, key_ref: Self::KeyRef<'a>) -> Option<Self::EntryMutRef<'_>>
where K: 'a {
self.entry_mut(&key_ref)
}

fn get<'a>(&self, key_ref: Self::KeyRef<'a>) -> Option<&Self::Value>
where K: 'a {
self.get(&key_ref)
}
fn get_mut<'a>(&mut self, key_ref: Self::KeyRef<'a>) -> Option<&mut Self::Value>
where K: 'a {
self.get_mut(&key_ref)
}

unsafe fn insert<'a>(
&mut self,
key_ref: Self::KeyRef<'a>,
) -> Result<&mut MaybeUninit<Self::Value>, &mut Self::Value>
where
K: 'a,
{
self.insert(key_ref)
}
unsafe fn insert_and_entry<'a>(
&mut self,
key_ref: Self::KeyRef<'a>,
) -> Result<Self::EntryMutRef<'_>, Self::EntryMutRef<'_>>
where
K: 'a,
{
self.insert_and_entry(key_ref)
}

fn iter(&self) -> Self::Iterator<'_> {
self.iter()
}
fn iter_mut(&mut self) -> Self::IteratorMut<'_> {
self.iter_mut()
}
}
3 changes: 3 additions & 0 deletions src/common/hashtable/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ mod unsized_hashtable;
mod utils;

pub use table0::Entry as HashtableEntry;
pub use traits::EntryMutRefLike as HashtableEntryMutRefLike;
pub use traits::EntryRefLike as HashtableEntryRefLike;
pub use traits::FastHash;
pub use traits::HashtableLike;
pub use traits::Keyable as HashtableKeyable;
pub use traits::UnsizedKeyable as HashtableUnsizedKeyable;

Expand Down
32 changes: 32 additions & 0 deletions src/common/hashtable/src/table0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use std::intrinsics::assume;
use std::mem::MaybeUninit;

use super::container::Container;
use super::traits::EntryMutRefLike;
use super::traits::EntryRefLike;
use super::traits::Keyable;

pub struct Entry<K, V> {
Expand Down Expand Up @@ -343,3 +345,33 @@ where K: Keyable
}
}
}

impl<'a, K: Keyable, V: 'a> EntryRefLike for &'a Entry<K, V> {
type KeyRef = K;
type ValueRef = &'a V;

fn key(&self) -> Self::KeyRef {
*(*self).key()
}
fn get(&self) -> Self::ValueRef {
(*self).get()
}
}

impl<'a, K: Keyable, V> EntryMutRefLike for &'a mut Entry<K, V> {
type KeyRef = K;
type Value = V;

fn key(&self) -> Self::KeyRef {
unsafe { self.key.assume_init() }
}
fn get(&self) -> &Self::Value {
unsafe { self.val.assume_init_ref() }
}
fn get_mut(&mut self) -> &mut Self::Value {
unsafe { self.val.assume_init_mut() }
}
fn write(&mut self, value: Self::Value) {
self.val.write(value);
}
}
81 changes: 80 additions & 1 deletion src/common/hashtable/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl FastHash for u128 {
use std::arch::x86_64::_mm_crc32_u64;
let mut high = CRC_A;
let mut low = CRC_B;
let y = [self as u64, (self >> 64) as u64];
let y = [*self as u64, (*self >> 64) as u64];
for x in y {
high = unsafe { _mm_crc32_u64(high as u64, x) as u32 };
low = unsafe { _mm_crc32_u64(low as u64, x) as u32 };
Expand Down Expand Up @@ -392,3 +392,82 @@ impl<const N: usize> FastHash for ([u64; N], NonZeroU64) {
}
}
}

pub trait EntryRefLike: Copy {
type KeyRef;
type ValueRef;

fn key(&self) -> Self::KeyRef;
fn get(&self) -> Self::ValueRef;
}

pub trait EntryMutRefLike {
type KeyRef;
type Value;

fn key(&self) -> Self::KeyRef;
fn get(&self) -> &Self::Value;
fn get_mut(&mut self) -> &mut Self::Value;
fn write(&mut self, value: Self::Value);
}

pub trait HashtableLike {
type Key: ?Sized;
type KeyRef<'a>: Copy
where Self::Key: 'a;
type Value;

type EntryRef<'a>: EntryRefLike<KeyRef = Self::KeyRef<'a>, ValueRef = &'a Self::Value>
where
Self: 'a,
Self::Key: 'a,
Self::Value: 'a;
type EntryMutRef<'a>: EntryMutRefLike<KeyRef = Self::KeyRef<'a>, Value = Self::Value>
where
Self: 'a,
Self::Key: 'a,
Self::Value: 'a;

type Iterator<'a>: Iterator<Item = Self::EntryRef<'a>>
where
Self: 'a,
Self::Key: 'a,
Self::Value: 'a;
type IteratorMut<'a>: Iterator<Item = Self::EntryMutRef<'a>>
where
Self: 'a,
Self::Key: 'a,
Self::Value: 'a;

fn entry<'a>(&self, key_ref: Self::KeyRef<'a>) -> Option<Self::EntryRef<'_>>
where Self::Key: 'a;
fn entry_mut<'a>(&mut self, key_ref: Self::KeyRef<'a>) -> Option<Self::EntryMutRef<'_>>
where Self::Key: 'a;

fn get<'a>(&self, key_ref: Self::KeyRef<'a>) -> Option<&Self::Value>
where Self::Key: 'a;
fn get_mut<'a>(&mut self, key_ref: Self::KeyRef<'a>) -> Option<&mut Self::Value>
where Self::Key: 'a;

/// # Safety
///
/// The uninitialized value of returned entry should be written immediately.
unsafe fn insert<'a>(
&mut self,
key_ref: Self::KeyRef<'a>,
) -> Result<&mut MaybeUninit<Self::Value>, &mut Self::Value>
where
Self::Key: 'a;
/// # Safety
///
/// The uninitialized value of returned entry should be written immediately.
unsafe fn insert_and_entry<'a>(
&mut self,
key_ref: Self::KeyRef<'a>,
) -> Result<Self::EntryMutRef<'_>, Self::EntryMutRef<'_>>
where
Self::Key: 'a;

fn iter(&self) -> Self::Iterator<'_>;
fn iter_mut(&mut self) -> Self::IteratorMut<'_>;
}
105 changes: 100 additions & 5 deletions src/common/hashtable/src/unsized_hashtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ use super::container::HeapContainer;
use super::table0::Entry;
use super::table0::Table0;
use super::table1::Table1;
use super::traits::EntryMutRefLike;
use super::traits::EntryRefLike;
use super::traits::FastHash;
use super::traits::HashtableLike;
use super::traits::Keyable;
use super::traits::UnsizedKeyable;
use super::utils::read_le;
Expand Down Expand Up @@ -118,7 +121,7 @@ where
+ self.table4.capacity()
}
#[inline(always)]
pub fn entry<'a>(&'a self, key: &K) -> Option<UnsizedHashtableEntryRef<'a, K, V>> {
pub fn entry(&self, key: &K) -> Option<UnsizedHashtableEntryRef<'_, K, V>> {
let key = key.as_bytes();
match key.len() {
_ if key.last().copied() == Some(0) => unsafe {
Expand Down Expand Up @@ -170,7 +173,7 @@ where
}
}
#[inline(always)]
pub fn entry_mut<'a>(&'a mut self, key: &K) -> Option<UnsizedHashtableEntryMutRef<'a, K, V>> {
pub fn entry_mut(&mut self, key: &K) -> Option<UnsizedHashtableEntryMutRef<'_, K, V>> {
let key = key.as_bytes();
match key.len() {
_ if key.last().copied() == Some(0) => unsafe {
Expand Down Expand Up @@ -868,7 +871,7 @@ impl<'a, K: ?Sized + UnsizedKeyable, V> UnsizedHashtableEntryMutRefInner<'a, K,
for i in (0..=7).rev() {
if bytes[i] != 0 {
return UnsizedKeyable::from_bytes(std::slice::from_raw_parts(
e.key() as *const _ as *const u8,
e.key.assume_init_ref() as *const _ as *const u8,
i + 1,
));
}
Expand All @@ -880,7 +883,7 @@ impl<'a, K: ?Sized + UnsizedKeyable, V> UnsizedHashtableEntryMutRefInner<'a, K,
for i in (0..=7).rev() {
if bytes[i] != 0 {
return UnsizedKeyable::from_bytes(std::slice::from_raw_parts(
e.key() as *const _ as *const u8,
e.key.assume_init_ref() as *const _ as *const u8,
i + 9,
));
}
Expand All @@ -892,7 +895,7 @@ impl<'a, K: ?Sized + UnsizedKeyable, V> UnsizedHashtableEntryMutRefInner<'a, K,
for i in (0..=7).rev() {
if bytes[i] != 0 {
return UnsizedKeyable::from_bytes(std::slice::from_raw_parts(
e.key() as *const _ as *const u8,
e.key.assume_init_ref() as *const _ as *const u8,
i + 17,
));
}
Expand Down Expand Up @@ -1035,3 +1038,95 @@ unsafe impl Keyable for FallbackKey {
self.hash
}
}

impl<'a, K: UnsizedKeyable + ?Sized + 'a, V: 'a> EntryRefLike
for UnsizedHashtableEntryRef<'a, K, V>
{
type KeyRef = &'a K;
type ValueRef = &'a V;

fn key(&self) -> Self::KeyRef {
(*self).key()
}
fn get(&self) -> Self::ValueRef {
(*self).get()
}
}

impl<'a, K: UnsizedKeyable + ?Sized + 'a, V: 'a> EntryMutRefLike
for UnsizedHashtableEntryMutRef<'a, K, V>
{
type KeyRef = &'a K;
type Value = V;

fn key(&self) -> Self::KeyRef {
self.key()
}
fn get(&self) -> &Self::Value {
self.get()
}
fn get_mut(&mut self) -> &mut Self::Value {
self.get_mut()
}
fn write(&mut self, value: Self::Value) {
self.write(value);
}
}

impl<V, A> HashtableLike for UnsizedHashtable<[u8], V, A>
where A: Allocator + Clone + Default
{
type Key = [u8];
type KeyRef<'a> = &'a [u8] where Self::Key:'a;
type Value = V;

type EntryRef<'a> = UnsizedHashtableEntryRef<'a, [u8], V> where Self:'a, V: 'a;
type EntryMutRef<'a> = UnsizedHashtableEntryMutRef<'a, [u8], V> where Self:'a, V: 'a;

type Iterator<'a> = UnsizedHashtableIter<'a, [u8], V> where Self:'a, V: 'a;
type IteratorMut<'a> = UnsizedHashtableIterMut<'a, [u8], V> where Self:'a, V: 'a;

fn entry<'a>(&self, key_ref: Self::KeyRef<'a>) -> Option<Self::EntryRef<'_>>
where Self::Key: 'a {
self.entry(key_ref)
}
fn entry_mut<'a>(&mut self, key_ref: Self::KeyRef<'a>) -> Option<Self::EntryMutRef<'_>>
where Self::Key: 'a {
self.entry_mut(key_ref)
}

fn get<'a>(&self, key_ref: Self::KeyRef<'a>) -> Option<&Self::Value>
where Self::Key: 'a {
self.get(key_ref)
}
fn get_mut<'a>(&mut self, key_ref: Self::KeyRef<'a>) -> Option<&mut Self::Value>
where Self::Key: 'a {
self.get_mut(key_ref)
}

unsafe fn insert<'a>(
&mut self,
key_ref: Self::KeyRef<'a>,
) -> Result<&mut MaybeUninit<Self::Value>, &mut Self::Value>
where
Self::Key: 'a,
{
self.insert(key_ref)
}
unsafe fn insert_and_entry<'a>(
&mut self,
key_ref: Self::KeyRef<'a>,
) -> Result<Self::EntryMutRef<'_>, Self::EntryMutRef<'_>>
where
Self::Key: 'a,
{
self.insert_and_entry(key_ref)
}

fn iter(&self) -> Self::Iterator<'_> {
self.iter()
}
fn iter_mut(&mut self) -> Self::IteratorMut<'_> {
self.iter_mut()
}
}
Loading

0 comments on commit 4308477

Please sign in to comment.