@Override public MarshalledEntry load(Object key) { if (!isValidKeyType(key)) { return null; } EntityManager em = emf.createEntityManager(); try { EntityTransaction txn = em.getTransaction(); long txnBegin = timeService.time(); txn.begin(); try { long entityFindBegin = timeService.time(); Object entity = em.find(configuration.entityClass(), key); stats.addEntityFind(timeService.time() - entityFindBegin); try { if (entity == null) return null; InternalMetadata m = null; if (configuration.storeMetadata()) { byte[] keyBytes; try { keyBytes = marshaller.objectToByteBuffer(key); } catch (Exception e) { throw new JpaStoreException("Failed to marshall key", e); } long metadataFindBegin = timeService.time(); MetadataEntity metadata = em.find(MetadataEntity.class, keyBytes); stats.addMetadataFind(timeService.time() - metadataFindBegin); if (metadata != null && metadata.getMetadata() != null) { try { m = (InternalMetadata) marshaller.objectFromByteBuffer(metadata.getMetadata()); } catch (Exception e) { throw new JpaStoreException("Failed to unmarshall metadata", e); } if (m.isExpired(timeService.wallClockTime())) { return null; } } } if (trace) log.trace("Loaded " + entity + " (" + m + ")"); return marshallerEntryFactory.newMarshalledEntry(key, entity, m); } finally { try { txn.commit(); stats.addReadTxCommitted(timeService.time() - txnBegin); } catch (Exception e) { stats.addReadTxFailed(timeService.time() - txnBegin); throw new JpaStoreException("Failed to load entry", e); } } } finally { if (txn != null && txn.isActive()) txn.rollback(); } } finally { em.close(); } }
private InternalMetadata getMetadata(EntityManager em, Object key) { byte[] keyBytes; try { keyBytes = marshaller.objectToByteBuffer(key); } catch (Exception e) { throw new JpaStoreException("Failed to marshall key", e); } MetadataEntity m = em.find(MetadataEntity.class, keyBytes); if (m == null) return null; try { return (InternalMetadata) marshaller.objectFromByteBuffer(m.getMetadata()); } catch (Exception e) { throw new JpaStoreException("Failed to unmarshall metadata", e); } }
private String toString(MetadataEntity metadata) { if (metadata == null || !metadata.hasBytes()) return "<no metadata>"; try { return marshaller.objectFromByteBuffer(metadata.getMetadata()).toString(); } catch (Exception e) { log.trace("Failed to unmarshall metadata", e); return "<metadata: " + e + ">"; } }
public boolean delete(Object key) { if (!isValidKeyType(key)) { return false; } EntityManager em = emf.createEntityManager(); try { long entityFindBegin = timeService.time(); Object entity = em.find(configuration.entityClass(), key); stats.addEntityFind(timeService.time() - entityFindBegin); if (entity == null) { return false; } MetadataEntity metadata = null; if (configuration.storeMetadata()) { byte[] keyBytes; try { keyBytes = marshaller.objectToByteBuffer(key); } catch (Exception e) { throw new JpaStoreException("Failed to marshall key", e); } long metadataFindBegin = timeService.time(); metadata = em.find(MetadataEntity.class, keyBytes); stats.addMetadataFind(timeService.time() - metadataFindBegin); } EntityTransaction txn = em.getTransaction(); if (trace) log.trace("Removing " + entity + "(" + toString(metadata) + ")"); long txnBegin = timeService.time(); txn.begin(); try { long entityRemoveBegin = timeService.time(); em.remove(entity); stats.addEntityRemove(timeService.time() - entityRemoveBegin); if (metadata != null) { long metadataRemoveBegin = timeService.time(); em.remove(metadata); stats.addMetadataRemove(timeService.time() - metadataRemoveBegin); } txn.commit(); stats.addRemoveTxCommitted(timeService.time() - txnBegin); return true; } catch (Exception e) { stats.addRemoveTxFailed(timeService.time() - txnBegin); throw new JpaStoreException("Exception caught in delete()", e); } finally { if (txn != null && txn.isActive()) txn.rollback(); } } finally { em.close(); } }
@Override public boolean contains(Object key) { if (!isValidKeyType(key)) { return false; } EntityManager em = emf.createEntityManager(); try { EntityTransaction txn = em.getTransaction(); long txnBegin = timeService.time(); txn.begin(); try { long entityFindBegin = timeService.time(); Object entity = em.find(configuration.entityClass(), key); stats.addEntityFind(timeService.time() - entityFindBegin); if (trace) log.trace("Entity " + key + " -> " + entity); try { if (entity == null) return false; if (configuration.storeMetadata()) { byte[] keyBytes; try { keyBytes = marshaller.objectToByteBuffer(key); } catch (Exception e) { throw new JpaStoreException("Cannot marshall key", e); } long metadataFindBegin = timeService.time(); MetadataEntity metadata = em.find(MetadataEntity.class, keyBytes); stats.addMetadataFind(timeService.time() - metadataFindBegin); if (trace) log.trace("Metadata " + key + " -> " + toString(metadata)); return metadata == null || metadata.expiration > timeService.wallClockTime(); } else { return true; } } finally { txn.commit(); stats.addReadTxCommitted(timeService.time() - txnBegin); } } catch (RuntimeException e) { stats.addReadTxFailed(timeService.time() - txnBegin); throw e; } finally { if (txn != null && txn.isActive()) txn.rollback(); } } finally { em.close(); } }
@Override public void purge(Executor threadPool, final PurgeListener listener) { ExecutorAllCompletionService eacs = new ExecutorAllCompletionService(threadPool); EntityManager em = emf.createEntityManager(); try { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<MetadataEntity> cq = cb.createQuery(MetadataEntity.class); Root root = cq.from(MetadataEntity.class); long currentTime = timeService.wallClockTime(); cq.where(cb.le(root.get(MetadataEntity.EXPIRATION), currentTime)); for (MetadataEntity metadata : em.createQuery(cq).getResultList()) { EntityTransaction txn = em.getTransaction(); final Object key; try { key = marshaller.objectFromByteBuffer(metadata.name); } catch (Exception e) { throw new JpaStoreException("Cannot unmarshall key", e); } long txnBegin = timeService.time(); txn.begin(); try { long metadataFindBegin = timeService.time(); metadata = em.find(MetadataEntity.class, metadata.name); stats.addMetadataFind(timeService.time() - metadataFindBegin); // check for transaction - I hope write skew check is done here if (metadata.expiration > currentTime) { txn.rollback(); continue; } long entityFindBegin = timeService.time(); Object entity = em.find(configuration.entityClass(), key); stats.addEntityFind(timeService.time() - entityFindBegin); if (entity != null) { // the entry may have been removed long entityRemoveBegin = timeService.time(); em.remove(entity); stats.addEntityRemove(timeService.time() - entityRemoveBegin); } long metadataRemoveBegin = timeService.time(); em.remove(metadata); stats.addMetadataRemove(timeService.time() - metadataRemoveBegin); txn.commit(); stats.addRemoveTxCommitted(timeService.time() - txnBegin); if (trace) log.trace("Expired " + key + " -> " + entity + "(" + toString(metadata) + ")"); if (listener != null) { eacs.submit( new Runnable() { @Override public void run() { listener.entryPurged(key); } }, null); } } catch (RuntimeException e) { stats.addRemoveTxFailed(timeService.time() - txnBegin); throw e; } finally { if (txn != null && txn.isActive()) { txn.rollback(); } } } } finally { em.close(); } eacs.waitUntilAllCompleted(); if (eacs.isExceptionThrown()) { throw new JpaStoreException(eacs.getFirstException()); } }