@@ -120,16 +120,50 @@ type (
120120
121121 // Views stores the view for all protocols
122122 Views struct {
123- vm map [string ]View
123+ snapshotID int
124+ snapshots map [int ]map [string ]int
125+ vm map [string ]View
124126 }
125127)
126128
127129func NewViews () * Views {
128130 return & Views {
129- vm : make (map [string ]View ),
131+ snapshotID : 0 ,
132+ snapshots : make (map [int ]map [string ]int ),
133+ vm : make (map [string ]View ),
130134 }
131135}
132136
137+ func (views * Views ) Snapshot () int {
138+ views .snapshotID ++
139+ views .snapshots [views .snapshotID ] = make (map [string ]int )
140+ keys := make ([]string , 0 , len (views .vm ))
141+ for key := range views .vm {
142+ keys = append (keys , key )
143+ }
144+ for _ , key := range keys {
145+ views.snapshots [views.snapshotID ][key ] = views .vm [key ].Snapshot ()
146+ }
147+ return views .snapshotID
148+ }
149+
150+ func (views * Views ) Revert (id int ) error {
151+ if id > views .snapshotID || id < 0 {
152+ return errors .Errorf ("invalid snapshot id %d, max id is %d" , id , views .snapshotID )
153+ }
154+ for k , v := range views .snapshots [id ] {
155+ if err := views .vm [k ].Revert (v ); err != nil {
156+ return err
157+ }
158+ }
159+ views .snapshotID = id
160+ // clean up snapshots that are not needed anymore
161+ for i := id + 1 ; i <= views .snapshotID ; i ++ {
162+ delete (views .snapshots , i )
163+ }
164+ return nil
165+ }
166+
133167func (views * Views ) Fork () * Views {
134168 fork := NewViews ()
135169 for key , view := range views .vm {
0 commit comments