@@ -5,24 +5,41 @@ use std::collections::BTreeMap;
5
5
use std:: convert:: TryFrom ;
6
6
use std:: iter:: FromIterator ;
7
7
8
+ const TOMBSTONE_KEY : & str = "*dead*" ;
9
+
10
+ #[ derive( Clone , Debug , PartialEq ) ]
11
+ struct Entry {
12
+ key : String ,
13
+ value : Value ,
14
+ }
15
+
8
16
#[ derive( Clone , PartialEq ) ]
9
- pub struct Object ( BTreeMap < String , Value > ) ;
17
+ pub struct Object ( Vec < Entry > ) ;
10
18
11
19
impl Object {
12
20
pub fn new ( ) -> Self {
13
- Self ( BTreeMap :: default ( ) )
21
+ Self ( Vec :: new ( ) )
14
22
}
15
23
16
24
pub fn get ( & self , key : & str ) -> Option < & Value > {
17
- self . 0 . get ( key)
25
+ self . 0
26
+ . iter ( )
27
+ . find ( |entry| entry. key == key)
28
+ . map ( |entry| & entry. value )
18
29
}
19
30
20
31
pub fn remove ( & mut self , key : & str ) -> Option < Value > {
21
- self . 0 . remove ( key)
32
+ self . 0
33
+ . iter_mut ( )
34
+ . find ( |entry| entry. key == key)
35
+ . map ( |entry| {
36
+ entry. key = TOMBSTONE_KEY . to_string ( ) ;
37
+ std:: mem:: replace ( & mut entry. value , Value :: Null )
38
+ } )
22
39
}
23
40
24
- pub fn iter ( & self ) -> std :: collections :: btree_map :: Iter < String , Value > {
25
- self . into_iter ( )
41
+ pub fn iter ( & self ) -> impl Iterator < Item = ( & String , & Value ) > {
42
+ ObjectIter :: new ( self )
26
43
}
27
44
28
45
fn len ( & self ) -> usize {
@@ -34,33 +51,92 @@ impl Object {
34
51
}
35
52
36
53
pub fn insert ( & mut self , key : String , value : Value ) -> Option < Value > {
37
- self . 0 . insert ( key, value)
54
+ match self . 0 . iter_mut ( ) . find ( |entry| & entry. key == & key) {
55
+ Some ( entry) => Some ( std:: mem:: replace ( & mut entry. value , value) ) ,
56
+ None => {
57
+ self . 0 . push ( Entry { key, value } ) ;
58
+ None
59
+ }
60
+ }
38
61
}
39
62
}
40
63
41
64
impl FromIterator < ( String , Value ) > for Object {
42
65
fn from_iter < T : IntoIterator < Item = ( String , Value ) > > ( iter : T ) -> Self {
43
- Object ( BTreeMap :: from_iter ( iter) )
66
+ let mut items: Vec < _ > = Vec :: new ( ) ;
67
+ for ( key, value) in iter {
68
+ items. push ( Entry { key, value } )
69
+ }
70
+ Object ( items)
71
+ }
72
+ }
73
+
74
+ pub struct ObjectOwningIter {
75
+ iter : std:: vec:: IntoIter < Entry > ,
76
+ }
77
+
78
+ impl Iterator for ObjectOwningIter {
79
+ type Item = ( String , Value ) ;
80
+
81
+ fn next ( & mut self ) -> Option < Self :: Item > {
82
+ while let Some ( entry) = self . iter . next ( ) {
83
+ if & entry. key != TOMBSTONE_KEY {
84
+ return Some ( ( entry. key , entry. value ) ) ;
85
+ }
86
+ }
87
+ None
44
88
}
45
89
}
46
90
47
91
impl IntoIterator for Object {
48
92
type Item = ( String , Value ) ;
49
93
50
- type IntoIter = std :: collections :: btree_map :: IntoIter < String , Value > ;
94
+ type IntoIter = ObjectOwningIter ;
51
95
52
96
fn into_iter ( self ) -> Self :: IntoIter {
53
- self . 0 . into_iter ( )
97
+ ObjectOwningIter {
98
+ iter : self . 0 . into_iter ( ) ,
99
+ }
54
100
}
55
101
}
56
102
57
- impl < ' a > IntoIterator for & ' a Object {
103
+ pub struct ObjectIter < ' a > {
104
+ iter : std:: slice:: Iter < ' a , Entry > ,
105
+ }
106
+
107
+ impl < ' a > ObjectIter < ' a > {
108
+ fn new ( object : & ' a Object ) -> Self {
109
+ Self {
110
+ iter : object. 0 . as_slice ( ) . iter ( ) ,
111
+ }
112
+ }
113
+ }
114
+ impl < ' a > Iterator for ObjectIter < ' a > {
58
115
type Item = ( & ' a String , & ' a Value ) ;
59
116
60
- type IntoIter = std:: collections:: btree_map:: Iter < ' a , String , Value > ;
117
+ fn next ( & mut self ) -> Option < Self :: Item > {
118
+ while let Some ( entry) = self . iter . next ( ) {
119
+ if & entry. key != TOMBSTONE_KEY {
120
+ return Some ( ( & entry. key , & entry. value ) ) ;
121
+ }
122
+ }
123
+ None
124
+ }
125
+ }
126
+
127
+ impl < ' a > IntoIterator for & ' a Object {
128
+ type Item = <ObjectIter < ' a > as Iterator >:: Item ;
129
+
130
+ type IntoIter = ObjectIter < ' a > ;
61
131
62
132
fn into_iter ( self ) -> Self :: IntoIter {
63
- self . 0 . iter ( )
133
+ ObjectIter :: new ( self )
134
+ }
135
+ }
136
+
137
+ impl CacheWeight for Entry {
138
+ fn indirect_weight ( & self ) -> usize {
139
+ self . key . indirect_weight ( ) + self . value . indirect_weight ( )
64
140
}
65
141
}
66
142
@@ -72,7 +148,7 @@ impl CacheWeight for Object {
72
148
73
149
impl Default for Object {
74
150
fn default ( ) -> Self {
75
- Self ( BTreeMap :: default ( ) )
151
+ Self ( Vec :: default ( ) )
76
152
}
77
153
}
78
154
@@ -96,7 +172,11 @@ pub enum Value {
96
172
97
173
impl Value {
98
174
pub fn object ( map : BTreeMap < String , Value > ) -> Self {
99
- Value :: Object ( Object ( map) )
175
+ let items = map
176
+ . into_iter ( )
177
+ . map ( |( key, value) | Entry { key, value } )
178
+ . collect ( ) ;
179
+ Value :: Object ( Object ( items) )
100
180
}
101
181
102
182
pub fn is_null ( & self ) -> bool {
0 commit comments