/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2013, Red Hat Inc. or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.hibernate.id.enhanced;

import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.hibernate.HibernateException;
import org.hibernate.id.IntegralDataTypeHolder;

import org.jboss.logging.Logger;

Slight variation from HiLoOptimizer, maintaining compatibility with the values generated by the legacy Hibernate hilo based generators.
Author:Steve Ebersole
/** * Slight variation from {@link HiLoOptimizer}, maintaining compatibility with the values generated by the * legacy Hibernate hilo based generators. * * @author Steve Ebersole */
public class LegacyHiLoAlgorithmOptimizer extends AbstractOptimizer { private static final Logger log = Logger.getLogger( LegacyHiLoAlgorithmOptimizer.class ); private final long initialMaxLo; private static class GenerationState { private long maxLo; private long lo; private IntegralDataTypeHolder hi; private IntegralDataTypeHolder lastSourceValue; private IntegralDataTypeHolder value; }
Constructs a LegacyHiLoAlgorithmOptimizer
Params:
  • returnClass – The Java type of the values to be generated
  • incrementSize – The increment size.
/** * Constructs a LegacyHiLoAlgorithmOptimizer * * @param returnClass The Java type of the values to be generated * @param incrementSize The increment size. */
public LegacyHiLoAlgorithmOptimizer(Class returnClass, int incrementSize) { super( returnClass, incrementSize ); if ( incrementSize < 1 ) { throw new HibernateException( "increment size cannot be less than 1" ); } if ( log.isTraceEnabled() ) { log.tracev( "Creating hilo optimizer (legacy) with [incrementSize={0}; returnClass={1}]", incrementSize, returnClass.getName() ); } initialMaxLo = incrementSize; } @Override public synchronized Serializable generate(AccessCallback callback) { final GenerationState generationState = locateGenerationState( callback.getTenantIdentifier() ); if ( generationState.lo > generationState.maxLo ) { generationState.lastSourceValue = callback.getNextValue(); generationState.lo = generationState.lastSourceValue.eq( 0 ) ? 1 : 0; generationState.hi = generationState.lastSourceValue.copy().multiplyBy( generationState.maxLo + 1 ); } generationState.value = generationState.hi.copy().add( generationState.lo++ ); return generationState.value.makeValue(); } private GenerationState noTenantState; private Map<String,GenerationState> tenantSpecificState; private GenerationState locateGenerationState(String tenantIdentifier) { if ( tenantIdentifier == null ) { if ( noTenantState == null ) { noTenantState = createGenerationState(); } return noTenantState; } else { GenerationState state; if ( tenantSpecificState == null ) { tenantSpecificState = new ConcurrentHashMap<String, GenerationState>(); state = createGenerationState(); tenantSpecificState.put( tenantIdentifier, state ); } else { state = tenantSpecificState.get( tenantIdentifier ); if ( state == null ) { state = createGenerationState(); tenantSpecificState.put( tenantIdentifier, state ); } } return state; } } private GenerationState createGenerationState() { final GenerationState state = new GenerationState(); state.maxLo = initialMaxLo; state.lo = initialMaxLo + 1; return state; } private GenerationState noTenantGenerationState() { if ( noTenantState == null ) { throw new IllegalStateException( "Could not locate previous generation state for no-tenant" ); } return noTenantState; } @Override public synchronized IntegralDataTypeHolder getLastSourceValue() { return noTenantGenerationState().lastSourceValue.copy(); } @Override public boolean applyIncrementSizeToSourceValues() { return false; }
Getter for property 'lastValue'.

Exposure intended for testing purposes.
Returns:Value for property 'lastValue'.
/** * Getter for property 'lastValue'. * <p/> * Exposure intended for testing purposes. * * @return Value for property 'lastValue'. */
@SuppressWarnings( {"UnusedDeclaration"}) public synchronized IntegralDataTypeHolder getLastValue() { return noTenantGenerationState().value; } }