public static Pair < ? extends UndoAction , TheHashinator > updateHashinator ( Class < ? extends TheHashinator > hashinatorImplementation , long version , byte configBytes [ ] , boolean cooked ) { //Use a cached/canonical hashinator if possible TheHashinator existingHashinator = m_cachedHashinators . get ( version ) ; if ( existingHashinator == null ) { existingHashinator = constructHashinator ( hashinatorImplementation , configBytes , cooked ) ; TheHashinator tempVal = m_cachedHashinators . putIfAbsent ( version , existingHashinator ) ; if ( tempVal != null ) { existingHashinator = tempVal ; } } //Do a CAS loop to maintain a global instance while ( true ) { final Pair < Long , ? extends TheHashinator > snapshot = instance . get ( ) ; if ( version > snapshot . getFirst ( ) ) { final Pair < Long , ? extends TheHashinator > update = Pair . of ( version , existingHashinator ) ; if ( instance . compareAndSet ( snapshot , update ) ) { if ( ! m_elasticallyModified ) { if ( ! update . getSecond ( ) . pIsPristine ( ) ) { // This is not a lock protected (atomic) but it should be fine because // release() should only be called by the one thread that successfully // updated the hashinator hostLogger . debug ( "The Hashinator has been elastically modified." ) ; m_elasticallyModified = true ; } } // Note: Only undo is ever called and only from a failure in @BalancePartitions return Pair . of ( new UndoAction ( ) { @ Override public void release ( ) { } @ Override public void undo ( ) { boolean rolledBack = instance . compareAndSet ( update , snapshot ) ; if ( ! rolledBack ) { hostLogger . info ( "Didn't roll back hashinator because it wasn't set to expected hashinator" ) ; } } } , existingHashinator ) ; } } else { return Pair . of ( new UndoAction ( ) { @ Override public void release ( ) { } @ Override public void undo ( ) { } } , existingHashinator ) ; } } }
Update the hashinator in a thread safe manner with a newer version of the hash function . A version number must be provided and the new config will only be used if it is greater than the current version of the hash function .