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

Implement storage (revision 2) module #311

Merged
merged 558 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
558 commits
Select commit Hold shift + click to select a range
46a300e
Merge branch 'master' of github.com:paritytech/ink into redo-init-and…
Robbepop May 6, 2020
f34389f
[core] apply rustfmt
Robbepop May 6, 2020
b7cd8be
[core] fix warnings related to Wasm compilation
Robbepop May 6, 2020
bdbd583
[core] add SpreadLayout impl for DynamicAllocator
Robbepop May 6, 2020
82a722e
[core] remove unused method on Bits256RefMut
Robbepop May 6, 2020
3abc99a
[core] apply rustfmt
Robbepop May 6, 2020
4e3ce32
[core] remove some unneded ToDo comments
Robbepop May 6, 2020
be13953
[core] transit to new traits for LazyIndexMap
Robbepop May 7, 2020
487dff0
[core] transit to new traits for storage::Vec
Robbepop May 7, 2020
63b5025
[core] transit to new traits for storage::Stash
Robbepop May 7, 2020
1954a09
[core] transit to new traits for storage::Bitvec
Robbepop May 7, 2020
ede8055
[core] transit to new traits for dynamic storage allocator
Robbepop May 7, 2020
f0c48ab
[core] transit to new traits for LazyHashMap
Robbepop May 7, 2020
4586f34
[core] transit to new traits for storage::HashMap
Robbepop May 7, 2020
f5ff4a3
[core] apply rustfmt
Robbepop May 7, 2020
c87034d
[core] remove old storage traits for storage::Pack
Robbepop May 7, 2020
e89ffd1
[core] transit to new storage traits for LazyArray
Robbepop May 7, 2020
41cf862
[core] transit to new storage traits for storage::SmallVec
Robbepop May 7, 2020
b00c458
[core] transit to new storage traits for the rest of the lazy abstrac…
Robbepop May 7, 2020
07296c2
[core] transit to new storage traits for storage::Box
Robbepop May 7, 2020
3250b96
[core] fix compile error in Drop impl for storage::Box
Robbepop May 7, 2020
e800f77
[core] remove old storage trait impls for Bits256
Robbepop May 7, 2020
c3cb918
[core] remove old storage trait impls for dynamic storage allocator
Robbepop May 7, 2020
e9d5876
[core] apply rustfmt
Robbepop May 7, 2020
abdbc82
[core] remove old traits module
Robbepop May 7, 2020
cbbbcc7
[core] replace KeyPtr2 usage with KeyPtr
Robbepop May 7, 2020
ee650de
[core] rename traits2 module to traits
Robbepop May 7, 2020
b585f2a
[core] apply rustfmt
Robbepop May 7, 2020
d252df1
[core] add Drop impl to storage::Vec
Robbepop May 7, 2020
d65b6bb
[core] don't clear storage if key is none for storage::Vec
Robbepop May 7, 2020
635fd9f
[core] impl Drop for storage::Stash
Robbepop May 7, 2020
9a8fbdc
[core] simplify trait bounds for LazyHashMap
Robbepop May 7, 2020
58b69b1
[core] impl Drop for storage::HashMap
Robbepop May 7, 2020
f5264b7
[core] add Drop impl for storage::SmallVec
Robbepop May 7, 2020
cbe5317
[core] add are_trait_objects lint as deny
Robbepop May 8, 2020
71fd6ae
[core] fix minor formatting issue
Robbepop May 8, 2020
0fbf5ac
[core] add storage2::Memory utility
Robbepop May 8, 2020
50a4718
[core] remove usage of storage::Pack from internals of storage::Bitvec
Robbepop May 8, 2020
c1a6985
[core] remove usage of storage::Pack from internals of storage::Stash
Robbepop May 8, 2020
a0a4f13
[core] remove usage of storage::Pack from internals of storage::HashMap
Robbepop May 8, 2020
a04db0e
[core] add better Debug impl for LazyIndexMap
Robbepop May 8, 2020
69862e9
[core] apply rustfmt
Robbepop May 8, 2020
5d06196
[core] improve Debug impl for LazyHashMap
Robbepop May 9, 2020
add9229
[core] improve Debug impl for lazy::Entry
Robbepop May 9, 2020
58bec7c
[core] improve Debug impl for LazyCell
Robbepop May 9, 2020
74f78b4
[core] improve Debug impl for LazyArray
Robbepop May 9, 2020
a3a6be1
[core] apply rustfmt
Robbepop May 9, 2020
68a8b8a
[core] add REQUIRES_DEEP_CLEAN_UP to SpreadLayout
Robbepop May 9, 2020
9640cec
[core] implement REQUIRES_DEEP_CLEAN_UP for all built-in types
Robbepop May 9, 2020
b95a7ed
[core] add non-storage trait impls for storage::HashMap
Robbepop May 9, 2020
f62a80e
[core] simplify traits bounds of SpreadLayout impl for storage::HashMap
Robbepop May 9, 2020
c84c9e6
[core] fix bug in Wasm compilation
Robbepop May 9, 2020
244ce97
[core] add initial unit tests for storage::HashMap
Robbepop May 9, 2020
2fc4e12
[core] allow loading without key from LazyHashMap
Robbepop May 9, 2020
7bab683
[core] merge storage::HashMap insert and insert_get and fix bugs with it
Robbepop May 9, 2020
a840ec8
[core] add new unit test for storage::HashMap
Robbepop May 9, 2020
92fd483
[core] generally allow lazy loading without keys for lazy abstractions
Robbepop May 9, 2020
996bb78
[core] apply rustfmt
Robbepop May 9, 2020
fff9a80
[core] remove outdated docs of storage::HashMap::insert
Robbepop May 9, 2020
cb34edb
[core] add unit test for storage::HashMap::contains_key
Robbepop May 9, 2020
7f90b14
[core] apply rustfmt to storage::HashMap unit tests
Robbepop May 9, 2020
018e5f6
[core] add unit test for storage::HashMap::{get, get_mut}
Robbepop May 9, 2020
a5eb767
[core] fix the doc comment of storage::HashMap::remove
Robbepop May 9, 2020
a1bd0ba
[core] add unit test for storage::HashMap::take
Robbepop May 9, 2020
5786266
[core] add unit test for storage::HashMap::insert
Robbepop May 9, 2020
b7e9195
[core] remove storage::HashMap::remove
Robbepop May 9, 2020
989f38b
[core] implement Iterator::count efficiently for storage::HashMap ite…
Robbepop May 9, 2020
c968895
[core] add prelude trait impls for crypto hashers
Robbepop May 9, 2020
e2864ee
[core] add unit test for storage::HashMap::iter
Robbepop May 9, 2020
2e99a7d
[core] remove outdated doc comment line
Robbepop May 9, 2020
7ffb304
[core] add doc comments to fowarding-to-packed utility functions
Robbepop May 9, 2020
c4f4610
[core] add some high-level documentation for some root storage2 modules
Robbepop May 9, 2020
c1c441a
[core] add some more high-level docs
Robbepop May 9, 2020
2aecb7d
[core] add return value to storage::Stash::defrag
Robbepop May 9, 2020
4ef116b
[core] add return value to storage::HashMap::defrag
Robbepop May 9, 2020
f23ddc9
[core] add unit test for storage::HashMap::{values, values_mut}
Robbepop May 9, 2020
9287708
[core] add tests for Iterator::size_hint impls of storage::Vec
Robbepop May 9, 2020
6374a10
[core] add unit test for storage::HashMap::keys
Robbepop May 9, 2020
01f9192
[core] add unit test for storage::HashMap::defrag
Robbepop May 9, 2020
ba04b06
[core] add unit tests for LazyIndexMap
Robbepop May 10, 2020
21efe5a
[core] remove lazy::Entry::take_value
Robbepop May 10, 2020
f17f074
[core] remove LazyIndexMap::take
Robbepop May 10, 2020
122251b
[core] remove Entry::set_state
Robbepop May 10, 2020
0c556b4
[core] remove Lazy{Array, HashMap}::take method
Robbepop May 10, 2020
a2286b6
[core] add unit test for LazyIndexMap::put
Robbepop May 10, 2020
eb65e00
[core] add unit test for LazyIndexMap::swap
Robbepop May 10, 2020
5964798
[core] apply rustfmt
Robbepop May 10, 2020
f50d659
[core] cover Default impl of LazyIndexMap with unit test
Robbepop May 10, 2020
4b54852
[core] move imports to top for LazyIndexMap .rs file
Robbepop May 10, 2020
9b38030
[core] refactor lazy::Entry internals a bit
Robbepop May 10, 2020
efa636a
[core] add unit tests for Index impl of storage::Vec
Robbepop May 10, 2020
098c21f
[core] add unit tests for Index impl of storage::SmallVec
Robbepop May 10, 2020
11fcf3a
[core] add tests for Index impl of StorageStash
Robbepop May 10, 2020
5fa4c5d
[core] improve panic message for Index{Mut} impl of storage::Stash
Robbepop May 10, 2020
8f53bfa
[core] add unit tests for Index{Mut} impl of storage::Stash
Robbepop May 10, 2020
750dd28
[core] extend unit test for storage::Stash::get
Robbepop May 10, 2020
7345251
[core] disable certain tests in --release mode testing
Robbepop May 10, 2020
bf5584b
[core] add unit test for LazyIndexMap::{get, get_mut}
Robbepop May 10, 2020
e92ff3e
[core] add some unit tests for LazyArray
Robbepop May 10, 2020
011d936
[core] add some more unit tests for LazyArray
Robbepop May 10, 2020
6970fc7
[core] add some more unit tests to LaryArray
Robbepop May 10, 2020
642217c
[core] apply rustfmt
Robbepop May 10, 2020
008ea74
[core] add unit tests for LazyCell
Robbepop May 11, 2020
b841e46
[core] add unit test for SpreadLayout impl of LazyCell
Robbepop May 11, 2020
436d536
[core] extend SpreadLayout test for LazyCell
Robbepop May 11, 2020
161d687
[core] extend SpreadLayout test to also cover the clear_spread impl
Robbepop May 11, 2020
370c056
[core] rename unit test for LazyCell
Robbepop May 11, 2020
0d48b35
[core] fix clippy warning
Robbepop May 11, 2020
6358e40
[core] fix some LazyCell cache entry in lazy form
Robbepop May 11, 2020
8a2183c
[core] add new unit test for Debug impl of lazy initialized LazyCell
Robbepop May 11, 2020
b4d4a70
[core] add more unit tests for lazily initialized LazyCell
Robbepop May 11, 2020
415ff70
[core] implement shallow clean-up of storage via LazyCell
Robbepop May 11, 2020
d4cd87c
[core] test that a lazily loaded LazyCell preserves its cached value
Robbepop May 11, 2020
6cdf7bc
[core] apply rustfmt
Robbepop May 11, 2020
1fbc81d
[core] add additional check for LazyCell cache preservation
Robbepop May 11, 2020
a6b040f
[core] fix bug in LazyIndexMap::clear_packed_at
Robbepop May 11, 2020
f778ccc
[core] add unit test for SpreadLayout impl of LazyIndexMap
Robbepop May 11, 2020
9d01301
[core] fix bug in LazyArray::clear_packed_at
Robbepop May 11, 2020
29e824b
[core] add unit test for SpreadLayout impl of LazyArray
Robbepop May 11, 2020
9cab25c
[core] make LazyArray::capacity and SmallVec::capcity more user friendly
Robbepop May 11, 2020
ad62f54
[core] remove unnecessary trait bounds
Robbepop May 11, 2020
2631567
[core] remove more unnecessary trait bounds
Robbepop May 11, 2020
7acbc25
[core] add initial unit test for LazyHashMap
Robbepop May 11, 2020
a8802a2
[core] add unit test for LazyHashMap::key_at
Robbepop May 11, 2020
c2f3738
[core] apply rustfmt
Robbepop May 11, 2020
9127a57
[core] indent a block in test
Robbepop May 11, 2020
7a1ba47
[core] add unit test for LazyHashMap::put_get
Robbepop May 11, 2020
8216d52
[core] add unit test for LazyHashMap::{get, get_mut}
Robbepop May 11, 2020
9a3455e
[core] add unit test for LazyHashMap::put
Robbepop May 11, 2020
dcdde2e
[core] add unit test for LazyHashMap::swap
Robbepop May 11, 2020
9e59e15
[core] make hash builders reset their accumulator upon finalization
Robbepop May 11, 2020
36ef90a
[core] add unit test for SpreadLayout impl of LazyHashMap
Robbepop May 11, 2020
e9d0d87
[core] fix unit test for LazyHashMap::key_at
Robbepop May 11, 2020
dfbe0e9
[core] add unit tests for SpreadLayout impl of storage::Vec
Robbepop May 12, 2020
dcedc81
[core] add unit tests for SpreadLayout impl of storage::SmallVec
Robbepop May 12, 2020
96bed80
[core] add unit tests for SpreadLayout impl of storage::Stash
Robbepop May 12, 2020
1b9bd9b
[core] apply rustfmt
Robbepop May 12, 2020
5e5ef04
[core] add unit tests for SpreadLayout impl of storage::HashMap
Robbepop May 12, 2020
928ee74
[core] add unit test for DynamicAllocation::key
Robbepop May 12, 2020
6c60470
[core] add unit tests for SpreadLayout impl of storage::Bitvec
Robbepop May 12, 2020
78b32b2
[core] fix LazyCell::get unit test
Robbepop May 12, 2020
c721e68
[core] remove unused dependencies from Cargo.toml
Robbepop May 12, 2020
b3dda7b
[core] add missing docs for storage::{Stash, HashMap}
Robbepop May 12, 2020
ec9de2a
[core] deny missing docs of public items
Robbepop May 12, 2020
1fe65af
[core] add Debug impl to storage::Box
Robbepop May 12, 2020
4625dd4
[core] add unit tests for storage::Box
Robbepop May 12, 2020
bb809f3
[core] remove internal Pack::{get, get_mut} methods
Robbepop May 12, 2020
a458630
[core] fix bug in storage::Memory::{get, get_mut} API
Robbepop May 12, 2020
897143f
[core] add unit tests for storage::Pack
Robbepop May 13, 2020
1104843
[core] improve storage::Pack unit tests
Robbepop May 13, 2020
53ad667
[core] experimental inline(never) for debug_assertions compilation
Robbepop May 13, 2020
0519721
[core] apply rustfmt
Robbepop May 13, 2020
551d158
[core] remove experimental #[inline(never)]
Robbepop May 13, 2020
25a3e2c
[core] add unit test for Default impl of storage::Pack
Robbepop May 13, 2020
73d3c67
[core] add unit tests for storage::Memory
Robbepop May 13, 2020
57f33d2
[core] fix a unit test for storage::Box
Robbepop May 13, 2020
bf2f703
[core] fix minor bug in BitRefMut utility of storage::Bitvec
Robbepop May 13, 2020
bdf51ec
[core] cover storage::Bitvec::get_mut in get_works unit test
Robbepop May 13, 2020
ad2f011
[core] add unit tests for BitRefMut utility of storage::Bitvec
Robbepop May 13, 2020
965b7c2
[core] apply rustfmt
Robbepop May 13, 2020
cccadf7
[core] improve panic message when encountering a double free
Robbepop May 13, 2020
c17735a
[core] adjust double free unit test for storage::Box
Robbepop May 13, 2020
58d7123
[core] improve double free of dynamic storage panic message
Robbepop May 13, 2020
a1c8d3b
[core] apply rustfmt
Robbepop May 13, 2020
689d772
[core] merge Bits256Ref and Bits256RefMut into ChunkRef<T>
Robbepop May 13, 2020
c195738
[core] split access.rs into bitref.rs and bitsref.rs
Robbepop May 13, 2020
597565f
[core] apply rustfmt
Robbepop May 13, 2020
0267278
[core] replace transmute with pointer cast
Robbepop May 13, 2020
2615700
[core] add comment to explain repr(C)
Robbepop May 13, 2020
312b943
[core] add PartialEq and Eq impls to BitRefMut
Robbepop May 13, 2020
f2200b0
[core] add unit tests for ChunkRef
Robbepop May 13, 2020
73dfea0
[core] add failure unit tests for dynamic storage allocator
Robbepop May 13, 2020
54eb932
Merge branch 'master' of github.com:paritytech/ink into redo-init-and…
Robbepop May 14, 2020
a37dbc6
[core] fix bug in SpreadLayout impl of Option<T>
Robbepop May 14, 2020
8003fcc
[core] add unit test for dynamic storage allocator SpreadLayout impl
Robbepop May 14, 2020
f30aa6e
[core] fix SpreadLayout impl for Result<T, E>
Robbepop May 14, 2020
c333304
[core] fix yet another bug in SpreadLayout impl of Result<T, E>
Robbepop May 14, 2020
350ad01
[core] move forward_supported_array_lens macro to usage site
Robbepop May 14, 2020
fcd3ee5
[core] refactor some code duplication with clear_spread_root_opt
Robbepop May 14, 2020
e44b874
[core] fix doc comment in storage::Pack
Robbepop May 14, 2020
164a817
[core] remove some unused unsafe blocks
Robbepop May 14, 2020
a3a99b0
fix typo
Robbepop May 14, 2020
b26eb3d
fix typo
Robbepop May 14, 2020
a866192
fix typo
Robbepop May 14, 2020
4d0fa7f
fix typo
Robbepop May 14, 2020
4e58ee3
fix typo
Robbepop May 14, 2020
da288bd
[core] remove usage of storage::Pack in dynamic storage allocator
Robbepop May 14, 2020
641fc7c
[core] improve panic message in Lazy::{get, get_mut}
Robbepop May 14, 2020
a8fc3e2
[core] add test for SpreadLayout::clear_spread impl of dynamic storag…
Robbepop May 14, 2020
3156d84
[core] remove code dupe
Robbepop May 14, 2020
32bac89
[core] refactor clear_spread_root_opt utility function
Robbepop May 14, 2020
c28ca4b
[core] implement SpreadLayout::REQUIRES_DEEP_CLEAN_UP for some types
Robbepop May 14, 2020
bbacb5e
[core] move from bool to u8 for Option and Result SpreadLayout impls
Robbepop May 14, 2020
915e129
[core] fix bug in SpreadLayout impl for Option
Robbepop May 14, 2020
0fcfdc3
fix typo
Robbepop May 14, 2020
0533517
[core] update LazyCell SAFETY comment
Robbepop May 14, 2020
4d934f9
Merge branch 'redo-init-and-flush' of github.com:paritytech/ink into …
Robbepop May 14, 2020
cfa4e99
[core] update Entry docs
Robbepop May 14, 2020
7fc236f
[core] remove unneeded code in lazy::Entry::pull_packed_root
Robbepop May 14, 2020
abe950a
fix typo
Robbepop May 15, 2020
3120149
fix typo
Robbepop May 15, 2020
26637f5
fix typo
Robbepop May 15, 2020
132c31f
fix typo
Robbepop May 15, 2020
942fc21
[core] remove commented out code
Robbepop May 15, 2020
8dca61b
Merge branch 'redo-init-and-flush' of github.com:paritytech/ink into …
Robbepop May 15, 2020
981ccbc
[core] add new unit test for dynamic storage allocator
Robbepop May 16, 2020
386554a
[core] refactor global storage allocator initialization routines
Robbepop May 16, 2020
9aa98df
[core] fix Wasm compilation errors
Robbepop May 16, 2020
6a4e988
[core] apply rustfmt
Robbepop May 16, 2020
72c8d24
[core] surpress bad clippy lint
Robbepop May 16, 2020
1d1cf88
[core] remove dead code
Robbepop May 16, 2020
7781e46
[core] improve call_setup_works test
Robbepop May 16, 2020
0141966
[core] fix bug in initialize_for for off-chain env
Robbepop May 16, 2020
8b0c43a
[core] initial steps to factor out BitStash from DynamicAllocator
Robbepop May 16, 2020
7707b60
[core] apply rustfmt
Robbepop May 17, 2020
c09c1d8
[core] add Derive impl for BitStash
Robbepop May 17, 2020
7cb766f
[core] make use of storage::BitStash from dynamic storage allocator
Robbepop May 17, 2020
87c9332
[core] add unit tests for storage::BitStash
Robbepop May 17, 2020
41df228
[core] apply rustfmt
Robbepop May 17, 2020
9c76b94
[core] remove invalid TODO comment
Robbepop May 17, 2020
bfdd049
[core] fix some out of bounds panic messages
Robbepop May 17, 2020
3c6fdff
[core] remove deliberate memory leak in test suite
Robbepop May 17, 2020
e732fbb
[core] fix build failure for Wasm target
Robbepop May 17, 2020
4b90999
[core] add unit tests for SpreadLayout & PackedLayout impls of primit…
Robbepop May 18, 2020
9dce884
[core] add unit tests for packed layout explicitely
Robbepop May 18, 2020
460114d
Fix some typos
ascjones May 18, 2020
013fe32
Add simple double ended iter test
ascjones May 19, 2020
de472da
typos
ascjones May 19, 2020
ff86777
comment typos
ascjones May 19, 2020
064b8ed
split hashmap to hash map in comments
ascjones May 19, 2020
4e2526d
Merge branch 'master' of github.com:paritytech/ink into redo-init-and…
Robbepop May 19, 2020
6f4ad98
Merge branch 'redo-init-and-flush' of github.com:paritytech/ink into …
Robbepop May 19, 2020
dd8e701
fix typo
Robbepop May 20, 2020
8abd87c
fix typo in unreachable! message
Robbepop May 20, 2020
94a210d
fix typo in expects message
Robbepop May 20, 2020
0afc002
fix typo
Robbepop May 20, 2020
2bf18eb
fix typo
Robbepop May 20, 2020
c51c5dd
[core] add more comments to storage2::HashMap::defrag
Robbepop May 20, 2020
c663917
[core] make early return for storage2::HashMap::defrag for limit = 0
Robbepop May 20, 2020
8c51af4
[core] improve storage2::HashMap::contains_key implementation
Robbepop May 20, 2020
96bac02
[core] rename new_vec_works test to new_works
Robbepop May 20, 2020
7f6fd36
[core] apply Andrew's suggestions (and more)
Robbepop May 20, 2020
9477306
[core] fix typo: increase -> decrease
Robbepop May 20, 2020
6e4abe3
[core] add panic to Bitvec::push in case it reached its maximum capacity
Robbepop May 20, 2020
c5dedc3
[core] update comments for storage bit stash
Robbepop May 20, 2020
c05739d
[core] add more explanation comments
Robbepop May 20, 2020
07d3c23
[core] some more renamings of test internals
Robbepop May 20, 2020
3308797
improve reasoning
Robbepop May 20, 2020
ac873eb
fix typo
Robbepop May 20, 2020
58f3645
Merge branch 'redo-init-and-flush' of github.com:paritytech/ink into …
Robbepop May 20, 2020
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
344 changes: 344 additions & 0 deletions core/src/storage/lazy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,344 @@
// Copyright 2019-2020 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::{
KeyPtr,
Pull,
Push,
StorageSize,
};
use core::cell::UnsafeCell;
use ink_primitives::Key;

/// A lazy storage entity.
///
/// This loads its value from storage upon first use.
///
/// # Note
///
/// Use this if the storage field doesn't need to be loaded in some or most cases.
#[derive(Debug)]
pub struct Lazy<T> {
kind: UnsafeCell<LazyKind<T>>,
}

impl<T> StorageSize for Lazy<T>
where
T: StorageSize,
{
const SIZE: u64 = <T as StorageSize>::SIZE;
}

impl<T> Pull for Lazy<T>
where
T: StorageSize + scale::Decode,
{
fn pull(key_ptr: &mut KeyPtr) -> Self {
Self::lazy(key_ptr.next_for::<T>())
}
}

impl<T> Push for Lazy<T>
where
T: Push,
{
fn push(&self, key_ptr: &mut KeyPtr) {
// We skip pushing to contract storage if we are still in unloaded form.
if let LazyKind::Occupied(occupied) = self.kind() {
occupied.value.push(key_ptr)
}
}
}

impl<T> Lazy<T> {
/// Creates an eagerly populated lazy storage value.
#[must_use]
pub fn new(value: T) -> Self {
Self {
kind: UnsafeCell::new(LazyKind::Occupied(OccupiedLazy::new(value))),
}
}

/// Creates a true lazy storage value for the given key.
#[must_use]
pub fn lazy(key: Key) -> Self {
Self {
kind: UnsafeCell::new(LazyKind::Vacant(VacantLazy::new(key))),
}
}

/// Returns a shared reference to the inner lazy kind.
#[must_use]
fn kind(&self) -> &LazyKind<T> {
// SAFETY: We just return a shared reference while the method receiver
// is a shared reference (&self) itself. So we respect normal
// Rust rules.
unsafe { &*self.kind.get() }
}

/// Returns an exclusive reference to the inner lazy kind.
#[must_use]
fn kind_mut(&mut self) -> &mut LazyKind<T> {
// SAFETY: We just return an exclusive reference while the method receiver
// is an exclusive reference (&mut self) itself. So we respect normal
// Rust rules.
unsafe { &mut *self.kind.get() }
}

/// Performs the given closure on the mutable lazy kind.
///
/// # Note
///
/// Actions on the mutable lazy kind are performed within the closure
/// to not leak exclusive references to it to the outside. This is important
/// since the `for_kind` method itself operates only on `&self`.
fn for_kind<F, R>(&self, f: F) -> R
where
F: FnOnce(&mut LazyKind<T>) -> R,
Robbepop marked this conversation as resolved.
Show resolved Hide resolved
{
// SAFETY: We operate on an exclusive reference on `LazyKind` within the
// given closure while our method receiver is only a shared reference.
// However, due to encapsulation of the exclusive reference within
// the given closure we cannot leak the exclusive reference outside
// of the closure. So the below action is safe in this regard.
f(unsafe { &mut *self.kind.get() })
Robbepop marked this conversation as resolved.
Show resolved Hide resolved
}
}

impl<T> Lazy<T>
where
T: scale::Decode,
{
/// Loads the value lazily from contract storage.
///
/// Does nothing if value has already been loaded.
fn load_value_lazily(&self) {
self.for_kind(|kind| {
if let LazyKind::Vacant(vacant) = kind {
let value = crate::env::get_contract_storage::<T>(vacant.key)
.expect("couldn't find contract storage entry")
.expect("couldn't properly decode contract storage entry");
*kind = LazyKind::Occupied(OccupiedLazy::new(value));
}
});
}

/// Returns a shared reference to the lazily loaded value.
///
/// # Note
///
/// This loads the value from the contract storage if this did not happed before.
///
/// # Panics
///
/// If loading from contract storage failed.
#[must_use]
pub fn get(&self) -> &T {
self.load_value_lazily();
match self.kind() {
LazyKind::Vacant(_) => panic!("expect occupied lazy here"),
LazyKind::Occupied(occupied) => &occupied.value,
}
}

/// Returns an exclusive reference to the lazily loaded value.
///
/// # Note
///
/// This loads the value from the contract storage if this did not happed before.
///
/// # Panics
///
/// If loading from contract storage failed.
#[must_use]
pub fn get_mut(&mut self) -> &mut T {
self.load_value_lazily();
match self.kind_mut() {
LazyKind::Vacant(_) => panic!("expect occupied lazy here"),
LazyKind::Occupied(occupied) => &mut occupied.value,
}
}
}

impl<T> From<T> for Lazy<T> {
fn from(value: T) -> Self {
Self::new(value)
}
}

impl<T> Default for Lazy<T>
where
T: Default,
{
fn default() -> Self {
Self::new(Default::default())
}
}

impl<T> core::cmp::PartialEq for Lazy<T>
where
T: PartialEq + scale::Decode,
{
fn eq(&self, other: &Self) -> bool {
PartialEq::eq(self.get(), other.get())
}
}

impl<T> core::cmp::Eq for Lazy<T> where T: Eq + scale::Decode {}

impl<T> core::cmp::PartialOrd for Lazy<T>
where
T: PartialOrd + scale::Decode,
{
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
PartialOrd::partial_cmp(self.get(), other.get())
}
fn lt(&self, other: &Self) -> bool {
PartialOrd::lt(self.get(), other.get())
}
fn le(&self, other: &Self) -> bool {
PartialOrd::le(self.get(), other.get())
}
fn ge(&self, other: &Self) -> bool {
PartialOrd::ge(self.get(), other.get())
}
fn gt(&self, other: &Self) -> bool {
PartialOrd::gt(self.get(), other.get())
}
}

impl<T> core::cmp::Ord for Lazy<T>
where
T: core::cmp::Ord + scale::Decode,
{
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
Ord::cmp(self.get(), other.get())
}
}

impl<T> core::fmt::Display for Lazy<T>
where
T: scale::Decode + core::fmt::Display,
{
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
core::fmt::Display::fmt(self.get(), f)
}
}

impl<T> core::hash::Hash for Lazy<T>
where
T: core::hash::Hash + scale::Decode,
{
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.get().hash(state);
}
}

impl<T> core::convert::AsRef<T> for Lazy<T>
where
T: scale::Decode,
{
fn as_ref(&self) -> &T {
self.get()
}
}

impl<T> core::convert::AsMut<T> for Lazy<T>
where
T: scale::Decode,
{
fn as_mut(&mut self) -> &mut T {
self.get_mut()
}
}

impl<T> ink_prelude::borrow::Borrow<T> for Lazy<T>
where
T: scale::Decode,
{
fn borrow(&self) -> &T {
self.get()
}
}

impl<T> ink_prelude::borrow::BorrowMut<T> for Lazy<T>
where
T: scale::Decode,
{
fn borrow_mut(&mut self) -> &mut T {
self.get_mut()
}
}

impl<T> core::ops::Deref for Lazy<T>
where
T: scale::Decode,
{
type Target = T;

fn deref(&self) -> &Self::Target {
self.get()
}
}

impl<T> core::ops::DerefMut for Lazy<T>
where
T: scale::Decode,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.get_mut()
}
}

/// The lazy storage entity can be in either of two states.
///
/// 1. It either is vacant and thus a real lazy storage entity that
/// waits until it is used for the first time in order to load its value
/// from the contract storage.
/// 2. It is actually an already occupied eager lazy.
#[derive(Debug)]
pub enum LazyKind<T> {
/// A true lazy storage entity that loads its contract storage value upon first use.
Vacant(VacantLazy),
/// An already loaded eager lazy storage entity.
Occupied(OccupiedLazy<T>),
}

/// The lazy storage entity is in a lazy state.
#[derive(Debug)]
pub struct VacantLazy {
/// The key to load the value from contract storage upon first use.
pub key: Key,
}

impl VacantLazy {
/// Creates a new truly lazy storage entity for the given key.
pub fn new(key: Key) -> Self {
Self { key }
}
}

/// An already loaded or otherwise occupied eager lazy storage entity.
#[derive(Debug)]
pub struct OccupiedLazy<T> {
/// The loaded value.
pub value: T,
}

impl<T> OccupiedLazy<T> {
/// Creates a new eager lazy storage entity with the given value.
pub fn new(value: T) -> Self {
Self { value }
}
}
Loading