HHH-14444 Avoid synchronization for multi-tenant generation in PooledLoThreadLocalOptimizer

Signed-off-by: Yoann Rodière <yoann@hibernate.org>
This commit is contained in:
Yoann Rodière 2021-02-08 13:27:54 +01:00 committed by Sanne Grinovero
parent 5c155f3f8d
commit 511dda7dee
1 changed files with 10 additions and 25 deletions

View File

@ -40,6 +40,9 @@ public class PooledLoThreadLocalOptimizer extends AbstractOptimizer {
private IntegralDataTypeHolder upperLimitValue; private IntegralDataTypeHolder upperLimitValue;
} }
private final ThreadLocal<GenerationState> singleTenantState = ThreadLocal.withInitial( GenerationState::new );
private final ThreadLocal<Map<String, GenerationState>> multiTenantStates = ThreadLocal.withInitial( HashMap::new );
/** /**
* Constructs a PooledLoThreadLocalOptimizer. * Constructs a PooledLoThreadLocalOptimizer.
* *
@ -56,17 +59,9 @@ public class PooledLoThreadLocalOptimizer extends AbstractOptimizer {
@Override @Override
public Serializable generate(AccessCallback callback) { public Serializable generate(AccessCallback callback) {
if ( callback.getTenantIdentifier() == null ) {
final GenerationState local = localAssignedIds.get();
return generate( local, callback );
}
synchronized (this) {
final GenerationState generationState = locateGenerationState( callback.getTenantIdentifier() ); final GenerationState generationState = locateGenerationState( callback.getTenantIdentifier() );
return generate( generationState, callback ); return generate( generationState, callback );
} }
}
private Serializable generate(GenerationState generationState, AccessCallback callback) { private Serializable generate(GenerationState generationState, AccessCallback callback) {
if ( generationState.value == null if ( generationState.value == null
@ -82,26 +77,16 @@ public class PooledLoThreadLocalOptimizer extends AbstractOptimizer {
return generationState.value.makeValueThenIncrement(); return generationState.value.makeValueThenIncrement();
} }
private Map<String, GenerationState> tenantSpecificState;
private final ThreadLocal<GenerationState> localAssignedIds = ThreadLocal.withInitial( GenerationState::new );
private GenerationState locateGenerationState(String tenantIdentifier) { private GenerationState locateGenerationState(String tenantIdentifier) {
if ( tenantIdentifier == null ) { if ( tenantIdentifier == null ) {
return localAssignedIds.get(); return singleTenantState.get();
} }
else { else {
GenerationState state; Map<String, GenerationState> states = multiTenantStates.get();
if ( tenantSpecificState == null ) { GenerationState state = states.get( tenantIdentifier );
tenantSpecificState = new HashMap<String, GenerationState>();
state = new GenerationState();
tenantSpecificState.put( tenantIdentifier, state );
}
else {
state = tenantSpecificState.get( tenantIdentifier );
if ( state == null ) { if ( state == null ) {
state = new GenerationState(); state = new GenerationState();
tenantSpecificState.put( tenantIdentifier, state ); states.put( tenantIdentifier, state );
}
} }
return state; return state;
} }