use std::borrow::Cow;
use std::fmt::Display;
use std::hash::{BuildHasher, Hasher};
use std::ops::RangeBounds;
use bytes::{BufMut, Bytes, BytesMut};
use itertools::Itertools;
use self::empty::EMPTY;
use crate::hash::HashCode;
use crate::types::{hash_datum, DatumRef, ToDatumRef, ToOwnedDatum, ToText};
use crate::util::row_serde::OrderedRowSerde;
use crate::util::value_encoding;
pub trait Row: Sized + std::fmt::Debug + PartialEq + Eq {
fn datum_at(&self, index: usize) -> DatumRef<'_>;
unsafe fn datum_at_unchecked(&self, index: usize) -> DatumRef<'_>;
fn len(&self) -> usize;
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
}
fn iter(&self) -> impl Iterator<Item = DatumRef<'_>>;
#[inline]
fn to_owned_row(&self) -> OwnedRow {
OwnedRow::new(self.iter().map(|d| d.to_owned_datum()).collect())
}
#[inline]
fn into_owned_row(self) -> OwnedRow {
self.to_owned_row()
}
#[inline]
fn value_serialize_into(&self, mut buf: impl BufMut) {
for datum in self.iter() {
value_encoding::serialize_datum_into(datum, &mut buf);
}
}
#[inline]
fn value_serialize(&self) -> Vec<u8> {
let estimate_size = self
.iter()
.map(value_encoding::estimate_serialize_datum_size)
.sum();
let mut buf = Vec::with_capacity(estimate_size);
self.value_serialize_into(&mut buf);
buf
}
#[inline]
fn value_serialize_bytes(&self) -> Bytes {
let estimate_size = self
.iter()
.map(value_encoding::estimate_serialize_datum_size)
.sum();
let mut buf = BytesMut::with_capacity(estimate_size);
self.value_serialize_into(&mut buf);
buf.freeze()
}
fn value_estimate_size(&self) -> usize {
self.iter()
.map(value_encoding::estimate_serialize_datum_size)
.sum()
}
#[inline]
fn memcmp_serialize_into(&self, serde: &OrderedRowSerde, buf: impl BufMut) {
serde.serialize(self, buf);
}
#[inline]
fn memcmp_serialize(&self, serde: &OrderedRowSerde) -> Vec<u8> {
let mut buf = Vec::with_capacity(self.len()); self.memcmp_serialize_into(serde, &mut buf);
buf
}
fn hash_datums_into<H: Hasher>(&self, state: &mut H) {
for datum in self.iter() {
hash_datum(datum, state);
}
}
fn hash<H: BuildHasher>(&self, hash_builder: H) -> HashCode<H> {
let mut hasher = hash_builder.build_hasher();
self.hash_datums_into(&mut hasher);
hasher.finish().into()
}
#[inline]
fn eq(this: &Self, other: impl Row) -> bool {
if this.len() != other.len() {
return false;
}
for i in (0..this.len()).rev() {
if this.datum_at(i) != other.datum_at(i) {
return false;
}
}
true
}
}
const fn assert_row<R: Row>(r: R) -> R {
r
}
pub trait RowExt: Row {
fn chain<R: Row>(self, other: R) -> Chain<Self, R>
where
Self: Sized,
{
assert_row(Chain::new(self, other))
}
fn project(self, indices: &[usize]) -> Project<'_, Self>
where
Self: Sized,
{
assert_row(Project::new(self, indices))
}
fn slice(self, range: impl RangeBounds<usize>) -> Slice<Self>
where
Self: Sized,
{
assert_row(Slice::new(self, range))
}
fn display(&self) -> impl Display + '_ {
struct D<'a, T: Row>(&'a T);
impl<T: Row> Display for D<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
self.0.iter().format_with(" | ", |datum, f| {
match datum {
None => f(&"NULL"),
Some(scalar) => f(&format_args!("{}", scalar.to_text())),
}
})
)
}
}
D(self)
}
fn is_null_at(&self, index: usize) -> bool {
self.datum_at(index).is_none()
}
}
impl<R: Row> RowExt for R {}
macro_rules! deref_forward_row {
() => {
fn datum_at(&self, index: usize) -> crate::types::DatumRef<'_> {
(**self).datum_at(index)
}
unsafe fn datum_at_unchecked(&self, index: usize) -> crate::types::DatumRef<'_> {
(**self).datum_at_unchecked(index)
}
fn len(&self) -> usize {
(**self).len()
}
fn is_empty(&self) -> bool {
(**self).is_empty()
}
fn iter(&self) -> impl Iterator<Item = crate::types::DatumRef<'_>> {
(**self).iter()
}
fn to_owned_row(&self) -> OwnedRow {
(**self).to_owned_row()
}
fn value_serialize_into(&self, buf: impl bytes::BufMut) {
(**self).value_serialize_into(buf)
}
fn value_serialize(&self) -> Vec<u8> {
(**self).value_serialize()
}
fn memcmp_serialize_into(
&self,
serde: &$crate::util::row_serde::OrderedRowSerde,
buf: impl bytes::BufMut,
) {
(**self).memcmp_serialize_into(serde, buf)
}
fn memcmp_serialize(&self, serde: &$crate::util::row_serde::OrderedRowSerde) -> Vec<u8> {
(**self).memcmp_serialize(serde)
}
fn hash<H: std::hash::BuildHasher>(&self, hash_builder: H) -> $crate::hash::HashCode<H> {
(**self).hash(hash_builder)
}
fn hash_datums_into<H: std::hash::Hasher>(&self, state: &mut H) {
(**self).hash_datums_into(state)
}
fn eq(this: &Self, other: impl Row) -> bool {
Row::eq(&(**this), other)
}
};
}
impl<R: Row> Row for &R {
deref_forward_row!();
}
impl<R: Row + Clone> Row for Cow<'_, R> {
deref_forward_row!();
fn into_owned_row(self) -> OwnedRow {
self.into_owned().into_owned_row()
}
}
impl<R: Row> Row for Box<R> {
deref_forward_row!();
fn into_owned_row(self) -> OwnedRow {
(*self).into_owned_row()
}
}
macro_rules! impl_slice_row {
() => {
#[inline]
fn datum_at(&self, index: usize) -> DatumRef<'_> {
self[index].to_datum_ref()
}
#[inline]
unsafe fn datum_at_unchecked(&self, index: usize) -> DatumRef<'_> {
self.get_unchecked(index).to_datum_ref()
}
#[inline]
fn len(&self) -> usize {
self.as_ref().len()
}
#[inline]
fn iter(&self) -> impl Iterator<Item = DatumRef<'_>> {
self.as_ref().iter().map(ToDatumRef::to_datum_ref)
}
};
}
impl<D: ToDatumRef> Row for &[D] {
impl_slice_row!();
}
impl<D: ToDatumRef, const N: usize> Row for [D; N] {
impl_slice_row!();
}
impl<D: ToDatumRef + Default, const N: usize> Row for ArrayVec<[D; N]> {
impl_slice_row!();
}
impl<R: Row> Row for Option<R> {
fn datum_at(&self, index: usize) -> DatumRef<'_> {
match self {
Some(row) => row.datum_at(index),
None => EMPTY.datum_at(index),
}
}
unsafe fn datum_at_unchecked(&self, index: usize) -> DatumRef<'_> {
match self {
Some(row) => row.datum_at_unchecked(index),
None => EMPTY.datum_at_unchecked(index),
}
}
fn len(&self) -> usize {
match self {
Some(row) => row.len(),
None => 0,
}
}
fn iter(&self) -> impl Iterator<Item = DatumRef<'_>> {
match self {
Some(row) => either::Either::Left(row.iter()),
None => either::Either::Right(EMPTY.iter()),
}
}
fn to_owned_row(&self) -> OwnedRow {
match self {
Some(row) => row.to_owned_row(),
None => OwnedRow::new(Vec::new()),
}
}
fn into_owned_row(self) -> OwnedRow {
match self {
Some(row) => row.into_owned_row(),
None => OwnedRow::new(Vec::new()),
}
}
fn value_serialize_into(&self, buf: impl BufMut) {
if let Some(row) = self {
row.value_serialize_into(buf);
}
}
fn memcmp_serialize_into(&self, serde: &OrderedRowSerde, buf: impl BufMut) {
if let Some(row) = self {
row.memcmp_serialize_into(serde, buf);
}
}
}
impl<R1: Row, R2: Row> Row for either::Either<R1, R2> {
fn datum_at(&self, index: usize) -> DatumRef<'_> {
either::for_both!(self, row => row.datum_at(index))
}
unsafe fn datum_at_unchecked(&self, index: usize) -> DatumRef<'_> {
either::for_both!(self, row => row.datum_at_unchecked(index))
}
fn len(&self) -> usize {
either::for_both!(self, row => row.len())
}
fn is_empty(&self) -> bool {
either::for_both!(self, row => row.is_empty())
}
fn iter(&self) -> impl Iterator<Item = DatumRef<'_>> {
self.as_ref().map_either(Row::iter, Row::iter)
}
fn to_owned_row(&self) -> OwnedRow {
either::for_both!(self, row => row.to_owned_row())
}
fn into_owned_row(self) -> OwnedRow {
either::for_both!(self, row => row.into_owned_row())
}
fn value_serialize_into(&self, buf: impl BufMut) {
either::for_both!(self, row => row.value_serialize_into(buf))
}
fn value_serialize(&self) -> Vec<u8> {
either::for_both!(self, row => row.value_serialize())
}
fn value_serialize_bytes(&self) -> Bytes {
either::for_both!(self, row => row.value_serialize_bytes())
}
fn memcmp_serialize_into(&self, serde: &OrderedRowSerde, buf: impl BufMut) {
either::for_both!(self, row => row.memcmp_serialize_into(serde, buf))
}
fn memcmp_serialize(&self, serde: &OrderedRowSerde) -> Vec<u8> {
either::for_both!(self, row => row.memcmp_serialize(serde))
}
fn hash_datums_into<H: Hasher>(&self, state: &mut H) {
either::for_both!(self, row => row.hash_datums_into(state))
}
fn hash<H: BuildHasher>(&self, hash_builder: H) -> HashCode<H> {
either::for_both!(self, row => row.hash(hash_builder))
}
fn eq(this: &Self, other: impl Row) -> bool {
either::for_both!(this, row => Row::eq(row, other))
}
}
mod chain;
mod compacted_row;
mod empty;
mod once;
mod ordered;
mod owned_row;
mod project;
mod repeat_n;
mod slice;
pub use ::tinyvec::ArrayVec;
pub use chain::Chain;
pub use compacted_row::CompactedRow;
pub use empty::{empty, Empty};
pub use once::{once, Once};
pub use owned_row::{OwnedRow, RowDeserializer};
pub use project::Project;
pub use repeat_n::{repeat_n, RepeatN};
pub use slice::Slice;