1
+ use std:: { cmp, iter:: FusedIterator , marker:: PhantomData } ;
2
+
1
3
use crate :: internal:: arena:: ArenaId ;
2
- use std:: cmp;
3
- use std:: iter:: FusedIterator ;
4
- use std:: marker:: PhantomData ;
5
4
6
5
const VALUES_PER_CHUNK : usize = 128 ;
7
6
8
- /// A `Mapping<TValue>` holds a collection of `TValue`s that can be addressed by `TId`s. You can
9
- /// think of it as a HashMap<TId, TValue>, optimized for the case in which we know the `TId`s are
10
- /// contiguous.
7
+ /// A `Mapping<TValue>` holds a collection of `TValue`s that can be addressed by
8
+ /// `TId`s. You can think of it as a HashMap<TId, TValue>, optimized for the
9
+ /// case in which we know the `TId`s are contiguous.
10
+ #[ derive( Clone ) ]
11
11
pub struct Mapping < TId , TValue > {
12
12
chunks : Vec < [ Option < TValue > ; VALUES_PER_CHUNK ] > ,
13
13
len : usize ,
14
+ max : usize ,
14
15
_phantom : PhantomData < TId > ,
15
16
}
16
17
@@ -35,6 +36,7 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
35
36
Self {
36
37
chunks,
37
38
len : 0 ,
39
+ max : 0 ,
38
40
_phantom : Default :: default ( ) ,
39
41
}
40
42
}
@@ -49,7 +51,8 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
49
51
50
52
/// Insert into the mapping with the specific value
51
53
pub fn insert ( & mut self , id : TId , value : TValue ) {
52
- let ( chunk, offset) = Self :: chunk_and_offset ( id. to_usize ( ) ) ;
54
+ let idx = id. to_usize ( ) ;
55
+ let ( chunk, offset) = Self :: chunk_and_offset ( idx) ;
53
56
54
57
// Resize to fit if needed
55
58
if chunk >= self . chunks . len ( ) {
@@ -58,6 +61,7 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
58
61
}
59
62
self . chunks [ chunk] [ offset] = Some ( value) ;
60
63
self . len += 1 ;
64
+ self . max = self . max . max ( idx) ;
61
65
}
62
66
63
67
/// Get a specific value in the mapping with bound checks
@@ -95,7 +99,9 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
95
99
/// Get a specific value in the mapping without bound checks
96
100
///
97
101
/// # Safety
98
- /// The caller must uphold most of the safety requirements for `get_unchecked`. i.e. the id having been inserted into the Mapping before.
102
+ /// The caller must uphold most of the safety requirements for
103
+ /// `get_unchecked`. i.e. the id having been inserted into the Mapping
104
+ /// before.
99
105
pub unsafe fn get_unchecked ( & self , id : TId ) -> & TValue {
100
106
let ( chunk, offset) = Self :: chunk_and_offset ( id. to_usize ( ) ) ;
101
107
self . chunks
@@ -108,7 +114,9 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
108
114
/// Get a specific value in the mapping without bound checks
109
115
///
110
116
/// # Safety
111
- /// The caller must uphold most of the safety requirements for `get_unchecked_mut`. i.e. the id having been inserted into the Mapping before.
117
+ /// The caller must uphold most of the safety requirements for
118
+ /// `get_unchecked_mut`. i.e. the id having been inserted into the Mapping
119
+ /// before.
112
120
pub unsafe fn get_unchecked_mut ( & mut self , id : TId ) -> & mut TValue {
113
121
let ( chunk, offset) = Self :: chunk_and_offset ( id. to_usize ( ) ) ;
114
122
self . chunks
@@ -128,6 +136,11 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
128
136
self . len == 0
129
137
}
130
138
139
+ /// Returns the maximum id that has been inserted
140
+ pub ( crate ) fn max ( & self ) -> usize {
141
+ self . max
142
+ }
143
+
131
144
/// Defines the number of slots that can be used
132
145
/// theses slots are not initialized
133
146
pub fn slots ( & self ) -> usize {
@@ -177,6 +190,35 @@ impl<'a, TId: ArenaId, TValue> Iterator for MappingIter<'a, TId, TValue> {
177
190
178
191
impl < ' a , TId : ArenaId , TValue > FusedIterator for MappingIter < ' a , TId , TValue > { }
179
192
193
+ #[ cfg( feature = "serde" ) ]
194
+ impl < K : ArenaId , V : serde:: Serialize > serde:: Serialize for Mapping < K , V > {
195
+ fn serialize < S : serde:: Serializer > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error > {
196
+ self . chunks
197
+ . iter ( )
198
+ . flatten ( )
199
+ . take ( self . max ( ) )
200
+ . collect :: < Vec < _ > > ( )
201
+ . serialize ( serializer)
202
+ }
203
+ }
204
+
205
+ #[ cfg( feature = "serde" ) ]
206
+ impl < ' de , K : ArenaId , V : serde:: Deserialize < ' de > > serde:: Deserialize < ' de > for Mapping < K , V > {
207
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
208
+ where
209
+ D : serde:: Deserializer < ' de > ,
210
+ {
211
+ let values = Vec :: < Option < V > > :: deserialize ( deserializer) ?;
212
+ let mut mapping = Mapping :: with_capacity ( values. len ( ) ) ;
213
+ for ( i, value) in values. into_iter ( ) . enumerate ( ) {
214
+ if let Some ( value) = value {
215
+ mapping. insert ( K :: from_usize ( i) , value) ;
216
+ }
217
+ }
218
+ Ok ( mapping)
219
+ }
220
+ }
221
+
180
222
#[ cfg( test) ]
181
223
mod tests {
182
224
use crate :: internal:: arena:: ArenaId ;
0 commit comments