/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.sail.rdbms.schema;
import java.sql.SQLException;
import java.sql.Types;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.openrdf.model.Value;
/**
* @author James Leigh
*/
public class LongIdSequence extends IdSequence {
private long SPAN = 1152921504606846975l;
private int SHIFT = Long.toBinaryString(SPAN).length();
private Number[] minIds;
private ConcurrentMap<ValueType, AtomicLong> seq = new ConcurrentHashMap<ValueType, AtomicLong>();
@Override
public int getShift() {
return SHIFT;
}
@Override
public int getJdbcIdType() {
return Types.BIGINT;
}
@Override
public String getSqlType() {
return "BIGINT";
}
@Override
public void init()
throws SQLException
{
minIds = new Number[ValueType.values().length];
for (int i = 0; i < minIds.length; i++) {
minIds[i] = i * (SPAN + 1);
}
if (getHashTable() != null) {
for (Number max : getHashTable().maxIds(getShift(), getMod())) {
ValueType code = valueOf(max);
if (max.longValue() > minId(code).longValue()) {
if (!seq.containsKey(code) || seq.get(code).longValue() < max.longValue()) {
seq.put(code, new AtomicLong(max.longValue()));
}
}
}
}
}
@Override
public Number idOf(Number number) {
return number.longValue();
}
@Override
public Number maxId(ValueType type) {
return minId(type).longValue() + SPAN;
}
@Override
public Number minId(ValueType type) {
return minIds[type.index()];
}
@Override
public Number nextId(Value value) {
ValueType code = valueOf(value);
if (!seq.containsKey(code)) {
seq.putIfAbsent(code, new AtomicLong(minId(code).longValue()));
}
return seq.get(code).incrementAndGet();
}
@Override
protected int shift(Number id) {
return (int)(id.longValue() >>> SHIFT);
}
}