@Override public DuplicateIDCache getDuplicateIDCache(final SimpleString address) { DuplicateIDCache cache = duplicateIDCaches.get(address); if (cache == null) { cache = new DuplicateIDCacheImpl(address, idCacheSize, storageManager, persistIDCache); DuplicateIDCache oldCache = duplicateIDCaches.putIfAbsent(address, cache); if (oldCache != null) { cache = oldCache; } } return cache; }
@Override public synchronized boolean atomicVerify(final byte[] duplID, final Transaction tx) throws Exception { if (contains(duplID)) { if (tx != null) { tx.markAsRollbackOnly(new ActiveMQDuplicateIdException()); } return false; } else { addToCache(duplID, tx, true); return true; } }
@Override public boolean contains(final byte[] duplID) { boolean contains = cache.get(new ByteArrayHolder(duplID)) != null; if (contains) { logger.trace("DuplicateIDCacheImpl(" + this.address + ")::constains found a duplicate " + describeID(duplID, 0)); } return contains; }
DuplicateIDCacheImpl cacheID = new DuplicateIDCacheImpl(ADDRESS, 10, journal, true); cacheID.addToCache(RandomUtil.randomBytes()); cacheID = new DuplicateIDCacheImpl(ADDRESS, 10, journal, true); cacheID.load(values); cacheID.addToCache(RandomUtil.randomBytes(), null);
@Override public void addToCache(final byte[] duplID) throws Exception { addToCache(duplID, null, false); }
@Override public synchronized void addToCache(final byte[] duplID, final Transaction tx, boolean instantAdd) throws Exception { long recordID = -1; if (tx == null) { if (persist) { recordID = storageManager.generateID(); storageManager.storeDuplicateID(address, duplID, recordID); } addToCacheInMemory(duplID, recordID); } else { if (persist) { recordID = storageManager.generateID(); storageManager.storeDuplicateIDTransactional(tx.getID(), address, duplID, recordID); tx.setContainsPersistent(); } if (instantAdd) { addToCacheInMemory(duplID, recordID); } else { if (logger.isTraceEnabled()) { logger.trace("DuplicateIDCacheImpl(" + this.address + ")::addToCache Adding duplicateID TX operation for " + describeID(duplID, recordID) + ", tx=" + tx); } // For a tx, it's important that the entry is not added to the cache until commit // since if the client fails then resends them tx we don't want it to get rejected tx.afterStore(new AddDuplicateIDOperation(duplID, recordID)); } } }
@Override public void addToCache(final byte[] duplID, final Transaction tx) throws Exception { addToCache(duplID, tx, false); }
@Override public DuplicateIDCache getDuplicateIDCache(final SimpleString address) { return new DuplicateIDCacheImpl(address, 2000, new NullStorageManager(), false); }
@Override public void deleteFromCache(byte[] duplicateID) throws Exception { if (logger.isTraceEnabled()) { logger.trace("DuplicateIDCacheImpl::deleteFromCache deleting id=" + describeID(duplicateID, 0)); } ByteArrayHolder bah = new ByteArrayHolder(duplicateID); Integer posUsed = cache.remove(bah); if (posUsed != null) { Pair<ByteArrayHolder, Long> id; synchronized (this) { id = ids.get(posUsed.intValue()); if (id.getA().equals(bah)) { id.setA(null); storageManager.deleteDuplicateID(id.getB()); if (logger.isTraceEnabled()) { logger.trace("DuplicateIDCacheImpl(" + this.address + ")::deleteFromCache deleting id=" + describeID(duplicateID, id.getB())); } id.setB(null); } } } }
@Test public void testDuplicateNonPersistent() throws Exception { createStorage(); DuplicateIDCache cache = new DuplicateIDCacheImpl(new SimpleString("test"), 2000, journal, false); TransactionImpl tx = new TransactionImpl(journal); for (int i = 0; i < 5000; i++) { byte[] bytes = RandomUtil.randomBytes(); cache.addToCache(bytes, tx); } tx.commit(); for (int i = 0; i < 5000; i++) { byte[] bytes = RandomUtil.randomBytes(); cache.addToCache(bytes, null); } } }
private synchronized void addToCacheInMemory(final byte[] duplID, final long recordID) { if (logger.isTraceEnabled()) { logger.trace("DuplicateIDCacheImpl(" + this.address + ")::addToCacheInMemory Adding " + describeID(duplID, recordID)); logger.trace("DuplicateIDCacheImpl(" + this.address + ")::addToCacheInMemory removing excess duplicateDetection " + describeID(id.getA().bytes, id.getB())); logger.trace("DuplicateIDCacheImpl(" + this.address + ")::addToCacheInMemory replacing old duplicateID by " + describeID(id.getA().bytes, id.getB())); logger.trace("DuplicateIDCacheImpl(" + this.address + ")::addToCacheInMemory Adding new duplicateID " + describeID(id.getA().bytes, id.getB()));
createStorage(); DuplicateIDCache cache = new DuplicateIDCacheImpl(new SimpleString("test"), 2000, journal, true);
logger.trace("DuplicateIDCacheImpl::load deleting id=" + describeID(id.getA(), id.getB())); logger.trace("DuplicateIDCacheImpl::load loading id=" + describeID(id.getA(), id.getB()));