@@ -5,24 +5,41 @@ use std::collections::BTreeMap;
55use std:: convert:: TryFrom ;
66use std:: iter:: FromIterator ;
77
8+ const TOMBSTONE_KEY : & str = "*dead*" ;
9+
10+ #[ derive( Clone , Debug , PartialEq ) ]
11+ struct Entry {
12+ key : String ,
13+ value : Value ,
14+ }
15+
816#[ derive( Clone , PartialEq ) ]
9- pub struct Object ( BTreeMap < String , Value > ) ;
17+ pub struct Object ( Vec < Entry > ) ;
1018
1119impl Object {
1220 pub fn new ( ) -> Self {
13- Self ( BTreeMap :: default ( ) )
21+ Self ( Vec :: new ( ) )
1422 }
1523
1624 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 )
1829 }
1930
2031 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+ } )
2239 }
2340
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 )
2643 }
2744
2845 fn len ( & self ) -> usize {
@@ -34,33 +51,92 @@ impl Object {
3451 }
3552
3653 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+ }
3861 }
3962}
4063
4164impl FromIterator < ( String , Value ) > for Object {
4265 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
4488 }
4589}
4690
4791impl IntoIterator for Object {
4892 type Item = ( String , Value ) ;
4993
50- type IntoIter = std :: collections :: btree_map :: IntoIter < String , Value > ;
94+ type IntoIter = ObjectOwningIter ;
5195
5296 fn into_iter ( self ) -> Self :: IntoIter {
53- self . 0 . into_iter ( )
97+ ObjectOwningIter {
98+ iter : self . 0 . into_iter ( ) ,
99+ }
54100 }
55101}
56102
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 > {
58115 type Item = ( & ' a String , & ' a Value ) ;
59116
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 > ;
61131
62132 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 ( )
64140 }
65141}
66142
@@ -72,7 +148,7 @@ impl CacheWeight for Object {
72148
73149impl Default for Object {
74150 fn default ( ) -> Self {
75- Self ( BTreeMap :: default ( ) )
151+ Self ( Vec :: default ( ) )
76152 }
77153}
78154
@@ -96,7 +172,11 @@ pub enum Value {
96172
97173impl Value {
98174 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) )
100180 }
101181
102182 pub fn is_null ( & self ) -> bool {
0 commit comments