private final void dcompute ( ) { // Work to do the distribution // Split out the keys into disjointly-homed sets of keys. // Find the split point. First find the range of home-indices. H2O cloud = H2O . CLOUD ; int lo = cloud . _memary . length , hi = - 1 ; for ( Key k : _keys ) { int i = k . home ( cloud ) ; if ( i < lo ) lo = i ; if ( i > hi ) hi = i ; // lo <= home(keys) <= hi } // Classic fork/join, but on CPUs. // Split into 3 arrays of keys: lo keys, hi keys and self keys final ArrayList < Key > locals = new ArrayList < Key > ( ) ; final ArrayList < Key > lokeys = new ArrayList < Key > ( ) ; final ArrayList < Key > hikeys = new ArrayList < Key > ( ) ; int self_idx = cloud . nidx ( H2O . SELF ) ; int mid = ( lo + hi ) >>> 1 ; // Mid-point for ( Key k : _keys ) { int idx = k . home ( cloud ) ; if ( idx == self_idx ) locals . add ( k ) ; else if ( idx < mid ) lokeys . add ( k ) ; else hikeys . add ( k ) ; } // Launch off 2 tasks for the other sets of keys, and get a place-holder // for results to block on. _lo = remote_compute ( lokeys ) ; _hi = remote_compute ( hikeys ) ; // Setup for local recursion: just use the local keys. if ( locals . size ( ) != 0 ) { // Shortcut for no local work _local = clone ( ) ; // 'this' is completer for '_local', so awaits _local completion _local . _is_local = true ; _local . _keys = locals . toArray ( new Key [ locals . size ( ) ] ) ; // Keys, including local keys (if any) _local . init ( ) ; // One-time top-level init H2O . submitTask ( _local ) ; // Begin normal execution on a FJ thread } else { tryComplete ( ) ; // No local work, so just immediate tryComplete } }
Override to specify local work