package org.gbif.occurrence.persistence; import org.gbif.occurrence.common.identifier.UniqueIdentifier; import org.gbif.occurrence.persistence.api.KeyLookupResult; import org.gbif.occurrence.persistence.api.OccurrenceKeyPersistenceService; import org.gbif.occurrence.persistence.keygen.KeyPersistenceService; import java.util.Set; import java.util.concurrent.TimeUnit; import com.google.common.collect.Sets; import com.google.inject.Inject; import com.google.inject.Singleton; import com.yammer.metrics.Metrics; import com.yammer.metrics.core.Meter; import com.yammer.metrics.core.Timer; import com.yammer.metrics.core.TimerContext; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @Singleton public class OccurrenceKeyPersistenceServiceImpl implements OccurrenceKeyPersistenceService { private final KeyPersistenceService<Integer> keyPersistenceService; private final Timer lockWaitTimer = Metrics.newTimer(OccurrenceKeyPersistenceServiceImpl.class, "lock wait", TimeUnit.MILLISECONDS, TimeUnit.SECONDS); private final Meter lockRequests = Metrics.newMeter(OccurrenceKeyPersistenceServiceImpl.class, "lock req", "lock req", TimeUnit.SECONDS); @Inject public OccurrenceKeyPersistenceServiceImpl(KeyPersistenceService<Integer> keyPersistenceService) { this.keyPersistenceService = checkNotNull(keyPersistenceService, "keyPersistenceService can't be null"); } @Override public KeyLookupResult findKey(Set<UniqueIdentifier> uniqueIdentifiers) { checkNotNull(uniqueIdentifiers, "uniqueIds can't be null"); if (uniqueIdentifiers.isEmpty()) { return null; } String datasetKey = uniqueIdentifiers.iterator().next().getDatasetKey().toString(); Set<String> uniqueStrings = Sets.newHashSet(); for (UniqueIdentifier uniqueIdentifier : uniqueIdentifiers) { uniqueStrings.add(uniqueIdentifier.getUnscopedUniqueString()); } return keyPersistenceService.findKey(uniqueStrings, datasetKey); } @Override public Set<Integer> findKeysByDataset(String datasetKey) { return keyPersistenceService.findKeysByScope(datasetKey); } /** * Hands off to the member KeyPersistenceService to generate a key for the given uniqueIds. * * @param uniqueIdentifiers the identifiers that all refer to the same occurrence * * @return a KeyLookupResult with the key for this occurrence * * @throws IllegalArgumentException if the uniqueIdentifiers set is empty */ @Override public KeyLookupResult generateKey(Set<UniqueIdentifier> uniqueIdentifiers) { checkArgument(!uniqueIdentifiers.isEmpty(), "uniqueIdentifiers can't be empty"); String datasetKey = uniqueIdentifiers.iterator().next().getDatasetKey().toString(); Set<String> uniqueStrings = Sets.newHashSetWithExpectedSize(uniqueIdentifiers.size()); for (UniqueIdentifier uniqueIdentifier : uniqueIdentifiers) { uniqueStrings.add(uniqueIdentifier.getUnscopedUniqueString()); } lockRequests.mark(); final TimerContext context = lockWaitTimer.time(); try { return keyPersistenceService.generateKey(uniqueStrings, datasetKey); } finally { context.stop(); } } /** * Hands off to the member KeyPersistenceService to delete the key. */ @Override public void deleteKey(int occurrenceKey, String datasetKey) { keyPersistenceService.deleteKey(occurrenceKey, datasetKey); } /** * Hands off to the member KeyPersistenceService to delete the key(s). * * @param uniqueIdentifiers corresponding to the lookup entries to delete */ @Override public void deleteKeyByUniqueIdentifiers(Set<UniqueIdentifier> uniqueIdentifiers) { String datasetKey = uniqueIdentifiers.iterator().next().getDatasetKey().toString(); Set<String> uniqueStrings = Sets.newHashSetWithExpectedSize(uniqueIdentifiers.size()); for (UniqueIdentifier uniqueIdentifier : uniqueIdentifiers) { uniqueStrings.add(uniqueIdentifier.getUnscopedUniqueString()); } keyPersistenceService.deleteKeyByUniques(uniqueStrings, datasetKey); } }