
ws.suid.SuidService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of suid-server-java Show documentation
Show all versions of suid-server-java Show documentation
Suid-server implementation for the Java EE technology stack.
The newest version!
package ws.suid;
import java.util.List;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
/**
* Service that fetches suid ID blocks from the database.
*
* This service looks up the default datasource and fetches suid blocks from it.
* There must be a table present named {@code `suid`} with columns {@code `block`}
* and {@code `shard`}. If records are present in this db, this service will generate
* suid blocks using the same shard. If no records are present, this service will
* insert the first record using {@code 0} as the shard id.
*
* @author Stijn de Witt [[email protected]]
*/
@Stateless
@LocalBean
public class SuidService {
/** Max. number of suid blocks that may be requested in a single request. */
public static final int MAX_REQUEST_BLOCKS = 8;
// small singleton to maintain a server-side ID pool
private static final class Generator {
static Generator instance;
Byte shard;
Suid block;
byte id;
private Generator() {}
public synchronized Suid next(SuidService suidService) {
if (id >= Suid.IDSIZE) {id = 0; block = null;}
if (block == null) {
block = suidService.nextBlocks(1)[0];
shard = Byte.valueOf(block.getShard());
}
return new Suid(block.getBlock(), id++, block.getShard());
}
public static final Generator get() {
return instance == null ? instance = new Generator() : instance;
}
}
@PersistenceContext
private EntityManager em;
/**
* Gets the next {@code count} ID blocks.
*
* Parameter count must be in the range {@code 1 .. MAX_REQUEST_BLOCKS}.
* If count is less than {@code 1}, it is set to {@code 1}.
* If {@code count} is greater than {@code MAX_REQUEST_BLOCKS}, it is set to {@code MAX_REQUEST_BLOCKS}.
*
* @param count The number of blocks to get. Is forced to be in range {@code 1 .. 8}.
* @return An array of block {@code Suid}s.
* @see #MAX_REQUEST_BLOCKS
*/
@Transactional(Transactional.TxType.REQUIRES_NEW)
@SuppressWarnings("unchecked")
public Suid[] nextBlocks(int count) {
if (count < 1) count = 1;
if (count > MAX_REQUEST_BLOCKS) count = MAX_REQUEST_BLOCKS;
Query query = em.createNamedQuery(SuidRecord.ALL, SuidRecord.class);
query.setFirstResult(0).setMaxResults(1);
List existing = (List) query.getResultList();
Byte shard = existing.isEmpty() ? Byte.valueOf((byte) 0) : existing.get(0).getShard();
Long block = existing.isEmpty() ? Long.valueOf(0L) : existing.get(0).getBlock();
SuidRecord[] blocks = new SuidRecord[count];
Suid[] results = new Suid[count];
for (int i=0; iThis method fetches a single Suid from a server-side pool of one block.
* As such, one in {@code Suid.IDSIZE} calls to this method will result in
* queries to the database to fetch the next block.
*
* @return The next unique Suid, never {@code null}.
*
* @see Suid#IDSIZE
*/
public Suid next() {
return Generator.get().next(this);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy