import React from 'react' ; import { throttle } from 'lodash' ; export default function useTtyBpfMapper ( tty , events ) { const bpfLookupTable = React . useMemo ( ( ) => { return events . map ( i => new Date ( i . time ) ) ; } , [ events ] ) ; const [ cursor , setCursor ] = React . useState ( ( ) => { return mapTtyToBpfEvent ( tty , bpfLookupTable ) ; } ) ; React . useEffect ( ( ) => { function onChange ( ) { const index = mapTtyToBpfEvent ( tty , bpfLookupTable ) ; setCursor ( index ) ; } const throttledOnChange = throttle ( onChange , 100 ) ; function cleanup ( ) { throttledOnChange . cancel ( ) ; tty . removeListener ( 'change' , throttledOnChange ) ; } tty . on ( 'change' , throttledOnChange ) ; return cleanup ; } , [ tty , events ] ) ; return cursor ; } function mapTtyToBpfEvent ( tty , bpfLookupTable = [ ] ) { if ( bpfLookupTable . length === 0 ) { return - 1 ; } if ( tty . currentEventIndex >= tty . _eventProvider . events . length ) { return bpfLookupTable . length ; } const ttyEvent = tty . _eventProvider . events [ tty . currentEventIndex ] ; return getEventIndex ( ttyEvent . time , bpfLookupTable ) ; } function getEventIndex ( datetime , lookupTable ) { const arr = lookupTable ; var low = 0 ; var hi = arr . length - 1 ; while ( hi - low > 1 ) { const mid = Math . floor ( ( low + hi ) / 2 ) ; if ( arr [ mid ] < datetime ) { low = mid ; } else { hi = mid ; } } if ( datetime - arr [ low ] <= arr [ hi ] - datetime ) { return low ; } return hi ; }