@@ -107,80 +107,84 @@ const OrderedKeyValue =
107107 key : string ;
108108 value : unknown ;
109109 position : number ;
110- clock : number ;
111110 hash : string ;
112111 } ,
113112 void ,
114113 unknown
115114 > {
116- const keys : { [ key : string ] : boolean } = { } ;
117- const positions : { [ key : string ] : { position : number ; clock : number } } = { } ;
118-
119115 let count = 0 ;
120- let clock = 0 ;
116+ const orderedLogEntries : LogEntry < DagCborEncodable > [ ] = [ ] ;
121117 for await ( const entry of log . traverse ( ) ) {
118+ orderedLogEntries . unshift ( entry )
119+ } ;
120+
121+ let finalEntries : { key : string ; value : unknown ; position : number , hash : string } [ ] = [ ]
122+ for ( const entry of orderedLogEntries ) {
122123 const { op, key, value } = entry . payload ;
123124 if ( ! key ) return ;
124125
125- if ( op === "PUT" && ! keys [ key ] ) {
126- keys [ key ] = true ;
126+ if ( op === "PUT" ) {
127+ finalEntries = finalEntries . filter ( e => e . key !== key ) ;
128+
127129 const putValue = value as { value : unknown ; position ?: number } ;
128130
129131 const hash = entry . hash ;
130132
131- const position =
132- positions [ key ] !== undefined
133- ? positions [ key ]
134- : putValue . position !== undefined
135- ? { position : putValue . position , clock }
136- : { position : - 1 , clock } ;
137- positions [ key ] = position ;
138-
139- count ++ ;
140- clock -- ;
141- yield { key , value : putValue . value , ... position , hash } ;
142- } else if ( op === "MOVE" && ! keys [ key ] && ! positions [ key ] ) { // À faire ici
143- positions [ key ] = { position : value as number , clock } ;
144- clock -- ;
145- } else if ( op === "DEL" && ! keys [ key ] ) {
146- keys [ key ] = true ;
133+ const position = putValue . position !== undefined ? putValue . position : - 1 ;
134+ finalEntries . push ( {
135+ key,
136+ value : putValue . value ,
137+ position,
138+ hash
139+ } ) ;
140+ count ++
141+ } else if ( op === "MOVE" ) {
142+ const existingEntry = finalEntries . find ( e => e . key === key ) ;
143+ if ( existingEntry ) {
144+ existingEntry . position = value as number ;
145+ finalEntries = [ ... finalEntries . filter ( e => e . key !== key ) , existingEntry ]
146+ }
147+ } else if ( op === "DEL" ) {
148+ finalEntries = finalEntries . filter ( e => e . key !== key ) ;
147149 }
148150 if ( amount !== undefined && count >= amount ) {
149151 break ;
150152 }
151153 }
154+
155+ // This is memory inefficient, but I haven't been able to think of a more elegant solution
156+ for ( const entry of finalEntries ) {
157+ yield entry ;
158+ }
152159 } ;
153160
154161 const all = async ( ) => {
155- const values : {
162+ const entries : {
156163 key : string ;
157164 value : unknown ;
158165 hash : string ;
159166 position : number ;
160- clock : number ;
161167 } [ ] = [ ] ;
162168 for await ( const entry of iterator ( ) ) {
163- values . unshift ( entry ) ;
169+ entries . push ( entry )
164170 }
165- const nonNegativePositionValues = values . map (
166- v => ( {
167- ...v ,
168- position : v . position >= 0 ? v . position : values . length + ( v . position )
169- } )
170- )
171171
172- return nonNegativePositionValues
173- . sort ( ( a , b ) => {
174- return a . position > b . position ? 1 : a . position === b . position ? (
175- a . clock - b . clock
176- ) : - 1
177- }
178- )
179- . map ( ( v ) => ( {
180- key : v . key ,
181- value : v . value ,
182- hash : v . hash ,
183- } ) ) ;
172+ const values : {
173+ key : string ;
174+ value : unknown ;
175+ hash : string ;
176+ } [ ] = [ ] ;
177+
178+ for ( const entry of entries ) {
179+ const position = entry . position >= 0 ? entry . position : ( entries . length + entry . position + 1 )
180+ values . splice ( position , 0 , {
181+ key : entry . key ,
182+ value : entry . value ,
183+ hash : entry . hash ,
184+ } )
185+ }
186+
187+ return values ;
184188 } ;
185189
186190 return {
0 commit comments