Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ManagedVecItem payload refactor #1614

Merged
merged 5 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

10 changes: 0 additions & 10 deletions contracts/feature-tests/basic-features/src/managed_vec_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,6 @@ pub trait ManagedVecFeatures {
mv.contains(&item)
}

#[endpoint]
fn managed_vec_array_push(
&self,
mut mv: ManagedVec<[u8; 5]>,
item: [u8; 5],
) -> ManagedVec<[u8; 5]> {
mv.push(item);
mv
}

#[endpoint]
fn managed_ref_explicit(&self, mv: ManagedVec<BigUint>, index: usize) -> BigUint {
let value: ManagedRef<BigUint> = mv.get(index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,6 @@ fn managed_vec_address_push_go() {
world().run("scenarios/managed_vec_address_push.scen.json");
}

#[test]
fn managed_vec_array_push_go() {
world().run("scenarios/managed_vec_array_push.scen.json");
}

#[test]
fn managed_vec_biguint_push_go() {
world().run("scenarios/managed_vec_biguint_push.scen.json");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,6 @@ fn managed_vec_address_push_rs() {
world().run("scenarios/managed_vec_address_push.scen.json");
}

#[test]
fn managed_vec_array_push_rs() {
world().run("scenarios/managed_vec_array_push.scen.json");
}

#[test]
fn managed_vec_biguint_push_rs() {
world().run("scenarios/managed_vec_biguint_push.scen.json");
Expand Down
3 changes: 1 addition & 2 deletions framework/base/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![no_std]
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

#![allow(deprecated)]

pub use multiversx_sc_derive::{self as derive, contract, module, proxy};
Expand Down
16 changes: 9 additions & 7 deletions framework/base/src/types/flags/esdt_local_role.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::{
codec,
codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode},
};

use super::EsdtLocalRoleFlags;
use crate as multiversx_sc;
use crate::{derive::type_abi, types::ManagedVecItem};
use crate::{
codec::{
self,
derive::{NestedDecode, NestedEncode, TopDecode, TopEncode},
},
derive::type_abi,
types::{ManagedVecItem, ManagedVecItemPayloadBuffer},
};

static ESDT_ROLE_NONE: &[u8] = &[];
static ESDT_ROLE_LOCAL_MINT: &[u8] = b"ESDTRoleLocalMint";
Expand Down Expand Up @@ -137,7 +139,7 @@ impl<'a> From<&'a [u8]> for EsdtLocalRole {
}

impl ManagedVecItem for EsdtLocalRole {
const PAYLOAD_SIZE: usize = 1;
type PAYLOAD = ManagedVecItemPayloadBuffer<1>;
const SKIPS_RESERIALIZATION: bool = false; // TODO: might be ok to be true, but needs testing
type Ref<'a> = Self;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl<M: ManagedTypeApi> EsdtTokenPaymentMultiValue<M> {
}

impl<M: ManagedTypeApi> ManagedVecItem for EsdtTokenPaymentMultiValue<M> {
const PAYLOAD_SIZE: usize = EsdtTokenPayment::<M>::PAYLOAD_SIZE;
type PAYLOAD = <EsdtTokenPayment<M> as ManagedVecItem>::PAYLOAD;
const SKIPS_RESERIALIZATION: bool = EsdtTokenPayment::<M>::SKIPS_RESERIALIZATION;
type Ref<'a> = Self;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,49 +1,40 @@
use super::ManagedVecItem;
use super::{ManagedVecItem, ManagedVecItemPayload};
use core::{cmp::Ordering, marker::PhantomData};

pub struct EncodedManagedVecItem<T: ManagedVecItem>
where
T: ManagedVecItem,
[(); <T as ManagedVecItem>::PAYLOAD_SIZE]:,
{
pub encoded: [u8; <T as ManagedVecItem>::PAYLOAD_SIZE],
pub encoded: T::PAYLOAD,
_phantom: PhantomData<T>,
}

impl<T> EncodedManagedVecItem<T>
where
T: ManagedVecItem,
[(); <T as ManagedVecItem>::PAYLOAD_SIZE]:,
{
pub(crate) fn decode(&self) -> T {
T::from_byte_reader(|item_bytes| {
item_bytes.copy_from_slice(&self.encoded);
item_bytes.copy_from_slice(self.encoded.payload_slice());
})
}
}

impl<T> PartialEq for EncodedManagedVecItem<T>
where
T: PartialEq + ManagedVecItem,
[(); <T as ManagedVecItem>::PAYLOAD_SIZE]:,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.decode().eq(&other.decode())
}
}

impl<T> Eq for EncodedManagedVecItem<T>
where
T: Eq + ManagedVecItem,
[(); <T as ManagedVecItem>::PAYLOAD_SIZE]:,
{
}
impl<T> Eq for EncodedManagedVecItem<T> where T: Eq + ManagedVecItem {}

impl<T> PartialOrd for EncodedManagedVecItem<T>
where
T: PartialOrd + ManagedVecItem,
[(); <T as ManagedVecItem>::PAYLOAD_SIZE]:,
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Expand All @@ -54,7 +45,6 @@ where
impl<T> Ord for EncodedManagedVecItem<T>
where
T: Ord + ManagedVecItem,
[(); <T as ManagedVecItem>::PAYLOAD_SIZE]:,
{
fn cmp(&self, other: &Self) -> Ordering {
self.decode().cmp(&other.decode())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
derive::type_abi,
};

use super::ManagedVec;
use super::{ManagedVec, ManagedVecItemPayloadBuffer};

#[type_abi]
#[derive(TopEncode, NestedEncode, Clone, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -158,7 +158,7 @@ where
T: ManagedVecItem,
{
ManagedVecItem::from_byte_reader(|bytes| {
let size = T::PAYLOAD_SIZE;
let size = T::payload_size();
bytes.copy_from_slice(&arr[*index..*index + size]);
*index += size;
})
Expand All @@ -169,7 +169,7 @@ where
T: ManagedVecItem,
{
ManagedVecItem::to_byte_writer(item, |bytes| {
let size = T::PAYLOAD_SIZE;
let size = T::payload_size();
arr[*index..*index + size].copy_from_slice(bytes);
*index += size;
});
Expand All @@ -185,7 +185,7 @@ impl<M: ManagedTypeApi> IntoMultiValue for EsdtTokenPayment<M> {
}

impl<M: ManagedTypeApi> ManagedVecItem for EsdtTokenPayment<M> {
const PAYLOAD_SIZE: usize = 16;
type PAYLOAD = ManagedVecItemPayloadBuffer<16>;
const SKIPS_RESERIALIZATION: bool = false;
type Ref<'a> = Self;

Expand Down
4 changes: 2 additions & 2 deletions framework/base/src/types/managed/wrapped/managed_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
types::{ManagedRef, ManagedType},
};

use super::ManagedVecItem;
use super::{ManagedVecItem, ManagedVecItemPayloadBuffer};

/// A very efficient optional managed type.
///
Expand Down Expand Up @@ -195,7 +195,7 @@ where
M: ManagedTypeApi,
T: ManagedType<M> + 'static,
{
const PAYLOAD_SIZE: usize = 4;
type PAYLOAD = ManagedVecItemPayloadBuffer<4>;
const SKIPS_RESERIALIZATION: bool = false;
type Ref<'a> = Self;

Expand Down
35 changes: 12 additions & 23 deletions framework/base/src/types/managed/wrapped/managed_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ where
/// Number of items.
#[inline]
pub fn len(&self) -> usize {
self.byte_len() / T::PAYLOAD_SIZE
self.byte_len() / T::payload_size()
}

#[inline]
Expand All @@ -132,7 +132,7 @@ where
}

pub fn try_get(&self, index: usize) -> Option<T::Ref<'_>> {
let byte_index = index * T::PAYLOAD_SIZE;
let byte_index = index * T::payload_size();
let mut load_result = Ok(());
let result = unsafe {
T::from_byte_reader_as_borrow(|dest_slice| {
Expand Down Expand Up @@ -178,7 +178,7 @@ where
}

pub(super) unsafe fn get_unsafe(&self, index: usize) -> T {
let byte_index = index * T::PAYLOAD_SIZE;
let byte_index = index * T::payload_size();
let mut load_result = Ok(());
let result = T::from_byte_reader(|dest_slice| {
load_result = self.buffer.load_slice(byte_index, dest_slice);
Expand All @@ -191,15 +191,15 @@ where
}

pub fn set(&mut self, index: usize, item: &T) -> Result<(), InvalidSliceError> {
let byte_index = index * T::PAYLOAD_SIZE;
let byte_index = index * T::payload_size();
item.to_byte_writer(|slice| self.buffer.set_slice(byte_index, slice))
}

/// Returns a new `ManagedVec`, containing the [start_index, end_index) range of elements.
/// Returns `None` if any index is out of range
pub fn slice(&self, start_index: usize, end_index: usize) -> Option<Self> {
let byte_start = start_index * T::PAYLOAD_SIZE;
let byte_end = end_index * T::PAYLOAD_SIZE;
let byte_start = start_index * T::payload_size();
let byte_end = end_index * T::payload_size();
let opt_buffer = self.buffer.copy_slice(byte_start, byte_end - byte_start);
opt_buffer.map(ManagedVec::new_from_raw_buffer)
}
Expand Down Expand Up @@ -314,10 +314,9 @@ where
fn with_self_as_slice<R, F>(&self, f: F) -> R
where
F: FnOnce(&[EncodedManagedVecItem<T>]) -> R,
[(); T::PAYLOAD_SIZE]:,
{
self.buffer.with_buffer_contents(|bytes| {
let item_len = bytes.len() / T::PAYLOAD_SIZE;
let item_len = bytes.len() / T::payload_size();
let values = Self::transmute_slice(bytes, item_len);
f(values)
})
Expand All @@ -326,14 +325,13 @@ where
fn with_self_as_slice_mut<F>(&mut self, f: F)
where
F: FnOnce(&mut [EncodedManagedVecItem<T>]) -> &[EncodedManagedVecItem<T>],
[(); T::PAYLOAD_SIZE]:,
{
self.buffer.with_buffer_contents_mut(|bytes| {
let item_len = bytes.len() / T::PAYLOAD_SIZE;
let item_len = bytes.len() / T::payload_size();
let values = Self::transmute_slice_mut(bytes, item_len);

let result = f(values);
let result_len = result.len() * T::PAYLOAD_SIZE;
let result_len = result.len() * T::payload_size();
Self::transmute_slice(result, result_len)
});
}
Expand All @@ -357,7 +355,6 @@ impl<M, T> ManagedVec<M, T>
where
M: ManagedTypeApi,
T: ManagedVecItem + Ord + Debug,
[(); T::PAYLOAD_SIZE]:,
{
pub fn sort(&mut self) {
self.with_self_as_slice_mut(|slice| {
Expand Down Expand Up @@ -398,10 +395,7 @@ where
});
}

pub fn sort_unstable(&mut self)
where
[(); T::PAYLOAD_SIZE]:,
{
pub fn sort_unstable(&mut self) {
self.with_self_as_slice_mut(|slice| {
slice.sort_unstable();
slice
Expand All @@ -411,7 +405,6 @@ where
pub fn sort_unstable_by<F>(&mut self, mut compare: F)
where
F: FnMut(&T, &T) -> Ordering,
[(); T::PAYLOAD_SIZE]:,
{
self.with_self_as_slice_mut(|slice| {
slice.sort_unstable_by(|a, b| compare(&a.decode(), &b.decode()));
Expand All @@ -423,7 +416,6 @@ where
where
F: FnMut(&T) -> K,
K: Ord,
[(); T::PAYLOAD_SIZE]:,
{
self.with_self_as_slice_mut(|slice| {
slice.sort_unstable_by_key(|a| f(&a.decode()));
Expand Down Expand Up @@ -463,10 +455,7 @@ where
M: ManagedTypeApi,
T: ManagedVecItem + PartialEq + Debug,
{
pub fn dedup(&mut self)
where
[(); T::PAYLOAD_SIZE]:,
{
pub fn dedup(&mut self) {
self.with_self_as_slice_mut(|slice| {
let same_bucket = |a, b| a == b;
let len = slice.len();
Expand Down Expand Up @@ -539,7 +528,7 @@ where
if self_item != other_item {
return false;
}
byte_index += T::PAYLOAD_SIZE;
byte_index += T::payload_size();
}
true
}
Expand Down
Loading
Loading