private Long deserializeRestoreInformation ( List < String > children , Map < String , Set < SnapshotInfo > > snapshotFragments ) throws Exception { try { int recover = m_action . ordinal ( ) ; Long clStartTxnId = null ; for ( String node : children ) { //This might be created before we are done fetching the restore info if ( node . equals ( "snapshot_id" ) ) { continue ; } byte [ ] data = null ; data = m_zk . getData ( VoltZK . restore + "/" + node , false , null ) ; String jsonData = new String ( data , "UTF8" ) ; JSONObject json = new JSONObject ( jsonData ) ; long maxTxnId = json . optLong ( "max" , Long . MIN_VALUE ) ; if ( maxTxnId != Long . MIN_VALUE ) { if ( clStartTxnId == null || maxTxnId > clStartTxnId ) { clStartTxnId = maxTxnId ; } } int remoteRecover = json . getInt ( "action" ) ; if ( remoteRecover != recover ) { String msg = "Database actions are not consistent. Remote node action is not 'recover'. " + "Please enter the same database action on the command-line." ; VoltDB . crashLocalVoltDB ( msg , false , null ) ; } JSONArray snapInfos = json . getJSONArray ( "snapInfos" ) ; int snapInfoCnt = snapInfos . length ( ) ; for ( int i = 0 ; i < snapInfoCnt ; i ++ ) { JSONObject jsonInfo = snapInfos . getJSONObject ( i ) ; SnapshotInfo info = new SnapshotInfo ( jsonInfo ) ; Set < SnapshotInfo > fragments = snapshotFragments . get ( info . nonce ) ; if ( fragments == null ) { fragments = new HashSet < SnapshotInfo > ( ) ; snapshotFragments . put ( info . nonce , fragments ) ; } fragments . add ( info ) ; } } return clStartTxnId ; } catch ( JSONException je ) { VoltDB . crashLocalVoltDB ( "Error exchanging snapshot information" , true , je ) ; } throw new RuntimeException ( "impossible" ) ; }
This function like all good functions does three things . It produces the command log start transaction Id . It produces a map of SnapshotInfo objects . And it errors if the remote start action does not match the local action .