@@ -17,6 +17,7 @@ import (
1717 "encoding/binary"
1818 "strings"
1919
20+ "github.com/consensys/go-corset/pkg/util"
2021 "github.com/consensys/go-corset/pkg/util/collection/array"
2122 "github.com/consensys/go-corset/pkg/util/collection/pool"
2223 "github.com/consensys/go-corset/pkg/util/word"
@@ -27,97 +28,107 @@ import (
2728// in some way. The input represents the original legacy format of trace files
2829// (i.e. without any additional header information prepended, etc).
2930func FromBytesLegacy (data []byte ) (WordHeap , []Module [word.BigEndian ], error ) {
31+ var modules []Module [word.BigEndian ]
32+ // Read out all column data
33+ heap , columns , error := readLegacyBytes (data )
34+ // Post process into structured form
35+ if error == nil {
36+ modules = groupLegacyColumns (columns )
37+ }
38+ //
39+ return heap , modules , error
40+ }
41+
42+ type legacyHeader struct {
43+ name string
44+ length uint
45+ width uint
46+ }
47+
48+ func groupLegacyColumns (columns []Column [word.BigEndian ]) []Module [word.BigEndian ] {
49+ var (
50+ modules []Module [word.BigEndian ]
51+ modmap map [string ]int = make (map [string ]int )
52+ )
53+ // Process each column one by one
54+ for _ , column := range columns {
55+ mod , col := splitQualifiedColumnName (column .Name )
56+ // Check whether module already allocated
57+ index , ok := modmap [mod ]
58+ //
59+ if ! ok {
60+ index = len (modules )
61+ modules = append (modules , Module [word.BigEndian ]{mod , nil })
62+ modmap [mod ] = index
63+ }
64+ // Update column name
65+ column .Name = col
66+ // Group it
67+ modules [index ].Columns = append (modules [index ].Columns , column )
68+ }
69+ //
70+ return modules
71+ }
72+
73+ func readLegacyBytes (data []byte ) (WordHeap , []Column [word.BigEndian ], error ) {
3074 var (
3175 buf = bytes .NewReader (data )
3276 heap = pool .NewSharedHeap [word.BigEndian ]()
3377 builder = array .NewDynamicBuilder (heap )
34- names []string
35- headers [][]legacyColumnHeader
36- modmap map [string ]uint = make (map [string ]uint )
3778 )
3879 // Read Number of BytesColumns
3980 var ncols uint32
4081 if err := binary .Read (buf , binary .BigEndian , & ncols ); err != nil {
4182 return WordHeap {}, nil , err
4283 }
84+ // Construct empty environment
85+ headers := make ([]legacyHeader , ncols )
86+ columns := make ([]Column [word.BigEndian ], ncols )
4387 // Read column headers
4488 for i := uint32 (0 ); i < ncols ; i ++ {
45- var header , err = readLegacyColumnHeader (buf )
89+ header , err : = readLegacyColumnHeader (buf )
4690 // Read column
4791 if err != nil {
4892 // Handle error
4993 return WordHeap {}, nil , err
5094 }
51- // Split out module and column name
52- mod , col := splitQualifiedColumnName (header .name )
53- // Lookup module index
54- index , ok := modmap [mod ]
55- // Check whether exists
56- if ! ok {
57- index = uint (len (headers ))
58- modmap [mod ] = index
59- //
60- headers = append (headers , nil )
61- names = append (names , mod )
62- }
63- // Reset header name
64- header .name = col
6595 // Assign header
66- headers [index ] = append ( headers [ index ], header )
96+ headers [i ] = header
6797 }
6898 // Determine byte slices
6999 offset := uint (len (data ) - buf .Len ())
70- c := make (chan legacyResult , ncols )
71- modules := make ([]Module [word.BigEndian ], len (headers ))
100+ c := make (chan util.Pair [uint , array.MutArray [word.BigEndian ]], ncols )
72101 // Dispatch go-routines
73- for i , ith := range headers {
74- modules [i ] = Module [word.BigEndian ]{
75- Name : names [i ],
76- Columns : make ([]Column [word.BigEndian ], len (ith )),
77- }
78- //
79- for j , jth := range ith {
80- // Calculate length (in bytes) of this column
81- nbytes := jth .width * jth .length
82- // Dispatch go-routine
83- go func (mid , cid int , offset uint , header legacyColumnHeader ) {
84- // Read column data
85- elements := readColumnData (header , data [offset :offset + nbytes ], builder )
86- // Package result
87- c <- legacyResult {mid , cid , elements }
88- }(i , j , offset , jth )
89- // Update byte offset
90- offset += nbytes
91- }
102+ for i := uint (0 ); i < uint (ncols ); i ++ {
103+ ith := headers [i ]
104+ // Calculate length (in bytes) of this column
105+ nbytes := ith .width * ith .length
106+ // Dispatch go-routine
107+ go func (i uint , offset uint ) {
108+ // Read column data
109+ elements := readColumnData (ith , data [offset :offset + nbytes ], builder )
110+ // Package result
111+ c <- util .NewPair (i , elements )
112+ }(i , offset )
113+ // Update byte offset
114+ offset += nbytes
92115 }
93116 // Collect results
94- for range ncols {
117+ for i := uint ( 0 ); i < uint ( ncols ); i ++ {
95118 // Read packaged result from channel
96119 res := <- c
97- // Determine column name
98- name := headers [res.module ][res. column ].name
120+ // Split qualified column name
121+ name := headers [res .Left ].name
99122 // Construct appropriate slice
100- modules [res .module ]. Columns [ res . column ] = Column [word.BigEndian ]{Name : name , Data : res .data }
123+ columns [res .Left ] = Column [word.BigEndian ]{Name : name , Data : res .Right }
101124 }
102125 // Done
103- return * heap .Localise (), modules , nil
104- }
105-
106- type legacyResult struct {
107- module int
108- column int
109- data array.MutArray [word.BigEndian ]
110- }
111-
112- type legacyColumnHeader struct {
113- name string
114- length uint
115- width uint
126+ return * heap .Localise (), columns , nil
116127}
117128
118129// Read the meta-data for a specific column in this trace file.
119- func readLegacyColumnHeader (buf * bytes.Reader ) (legacyColumnHeader , error ) {
120- var header legacyColumnHeader
130+ func readLegacyColumnHeader (buf * bytes.Reader ) (legacyHeader , error ) {
131+ var header legacyHeader
121132 // Qualified column name length
122133 var nameLen uint16
123134 // Read column name length
@@ -149,7 +160,7 @@ func readLegacyColumnHeader(buf *bytes.Reader) (legacyColumnHeader, error) {
149160 return header , nil
150161}
151162
152- func readColumnData (header legacyColumnHeader , bytes []byte , heap ArrayBuilder ) array.MutArray [word.BigEndian ] {
163+ func readColumnData (header legacyHeader , bytes []byte , heap ArrayBuilder ) array.MutArray [word.BigEndian ] {
153164 // Handle special cases
154165 switch header .width {
155166 case 1 :
@@ -180,7 +191,7 @@ func areAllBits(bytes []byte) bool {
180191 return true
181192}
182193
183- func readBitColumnData (header legacyColumnHeader , bytes []byte ) array.MutArray [word.BigEndian ] {
194+ func readBitColumnData (header legacyHeader , bytes []byte ) array.MutArray [word.BigEndian ] {
184195 arr := array.NewBitArray [word.BigEndian ](header .length )
185196 //
186197 for i := uint (0 ); i < header .length ; i ++ {
@@ -208,7 +219,7 @@ func readByteColumnData(length uint, bytes []byte, start, stride uint) array.Mut
208219 return & arr
209220}
210221
211- func readWordColumnData (header legacyColumnHeader , bytes []byte ) array.MutArray [word.BigEndian ] {
222+ func readWordColumnData (header legacyHeader , bytes []byte ) array.MutArray [word.BigEndian ] {
212223 var (
213224 arr = array .NewSmallArray [uint16 , word.BigEndian ](header .length , header .width * 8 )
214225 offset = uint (0 )
@@ -238,7 +249,7 @@ func readWordColumnData(header legacyColumnHeader, bytes []byte) array.MutArray[
238249 return & arr
239250}
240251
241- func readDWordColumnData (header legacyColumnHeader , bytes []byte ) array.MutArray [word.BigEndian ] {
252+ func readDWordColumnData (header legacyHeader , bytes []byte ) array.MutArray [word.BigEndian ] {
242253 var (
243254 arr = array .NewSmallArray [uint32 , word.BigEndian ](header .length , header .width * 8 )
244255 offset = uint (0 )
@@ -260,7 +271,7 @@ func readDWordColumnData(header legacyColumnHeader, bytes []byte) array.MutArray
260271 return & arr
261272}
262273
263- func readQWordColumnData (header legacyColumnHeader , bytes []byte , builder ArrayBuilder ) array.MutArray [word.BigEndian ] {
274+ func readQWordColumnData (header legacyHeader , bytes []byte , builder ArrayBuilder ) array.MutArray [word.BigEndian ] {
264275 var (
265276 arr = builder .NewArray (header .length , header .width * 8 )
266277 offset = uint (0 )
@@ -277,7 +288,7 @@ func readQWordColumnData(header legacyColumnHeader, bytes []byte, builder ArrayB
277288}
278289
279290// Read column data which is has arbitrary width
280- func readArbitraryColumnData (header legacyColumnHeader , bytes []byte , builder ArrayBuilder ,
291+ func readArbitraryColumnData (header legacyHeader , bytes []byte , builder ArrayBuilder ,
281292) array.MutArray [word.BigEndian ] {
282293 var (
283294 arr = builder .NewArray (header .length , header .width * 8 )
0 commit comments