@Override public Map<Sha256Hash, Long> lookupStreamIdsByHash(Transaction t, final Set<Sha256Hash> hashes) { if (hashes.isEmpty()) { return ImmutableMap.of(); } SnapshotsStreamHashAidxTable idx = tables.getSnapshotsStreamHashAidxTable(t); Set<SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxRow> rows = getHashIndexRowsForHashes(hashes); Multimap<SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxRow, SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxColumnValue> m = idx.getRowsMultimap(rows); Map<Long, Sha256Hash> hashForStreams = Maps.newHashMap(); for (SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxRow r : m.keySet()) { for (SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxColumnValue v : m.get(r)) { Long streamId = v.getColumnName().getStreamId(); Sha256Hash hash = r.getHash(); if (hashForStreams.containsKey(streamId)) { AssertUtils.assertAndLog(log, hashForStreams.get(streamId).equals(hash), "(BUG) Stream ID has 2 different hashes: " + streamId); } hashForStreams.put(streamId, hash); } } Map<Long, StreamMetadata> metadata = getMetadata(t, hashForStreams.keySet()); Map<Sha256Hash, Long> ret = Maps.newHashMap(); for (Map.Entry<Long, StreamMetadata> e : metadata.entrySet()) { if (e.getValue().getStatus() != Status.STORED) { continue; } Sha256Hash hash = hashForStreams.get(e.getKey()); ret.put(hash, e.getKey()); } return ret; }
@Override protected void putMetadataAndHashIndexTask(Transaction t, Map<Long, StreamMetadata> streamIdsToMetadata) { SnapshotsStreamMetadataTable mdTable = tables.getSnapshotsStreamMetadataTable(t); Map<Long, StreamMetadata> prevMetadatas = getMetadata(t, streamIdsToMetadata.keySet()); Map<SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow, StreamMetadata> rowsToStoredMetadata = Maps.newHashMap(); Map<SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow, StreamMetadata> rowsToUnstoredMetadata = Maps.newHashMap(); for (Entry<Long, StreamMetadata> e : streamIdsToMetadata.entrySet()) { long streamId = e.getKey(); StreamMetadata metadata = e.getValue(); StreamMetadata prevMetadata = prevMetadatas.get(streamId); if (metadata.getStatus() == Status.STORED) { if (prevMetadata == null || prevMetadata.getStatus() != Status.STORING) { // This can happen if we cleanup old streams. throw new TransactionFailedRetriableException("Cannot mark a stream as stored that isn't currently storing: " + prevMetadata); } rowsToStoredMetadata.put(SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow.of(streamId), metadata); } else if (metadata.getStatus() == Status.STORING) { // This will prevent two users trying to store the same id. if (prevMetadata != null) { throw new TransactionFailedRetriableException("Cannot reuse the same stream id: " + streamId); } rowsToUnstoredMetadata.put(SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow.of(streamId), metadata); } } putHashIndexTask(t, rowsToStoredMetadata); Map<SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow, StreamMetadata> rowsToMetadata = Maps.newHashMap(); rowsToMetadata.putAll(rowsToStoredMetadata); rowsToMetadata.putAll(rowsToUnstoredMetadata); mdTable.putMetadata(rowsToMetadata); }
@Override public Map<Sha256Hash, Long> lookupStreamIdsByHash(Transaction t, final Set<Sha256Hash> hashes) { if (hashes.isEmpty()) { return ImmutableMap.of(); } SnapshotsStreamHashAidxTable idx = tables.getSnapshotsStreamHashAidxTable(t); Set<SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxRow> rows = getHashIndexRowsForHashes(hashes); Multimap<SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxRow, SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxColumnValue> m = idx.getRowsMultimap(rows); Map<Long, Sha256Hash> hashForStreams = Maps.newHashMap(); for (SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxRow r : m.keySet()) { for (SnapshotsStreamHashAidxTable.SnapshotsStreamHashAidxColumnValue v : m.get(r)) { Long streamId = v.getColumnName().getStreamId(); Sha256Hash hash = r.getHash(); if (hashForStreams.containsKey(streamId)) { AssertUtils.assertAndLog(log, hashForStreams.get(streamId).equals(hash), "(BUG) Stream ID has 2 different hashes: " + streamId); } hashForStreams.put(streamId, hash); } } Map<Long, StreamMetadata> metadata = getMetadata(t, hashForStreams.keySet()); Map<Sha256Hash, Long> ret = Maps.newHashMap(); for (Map.Entry<Long, StreamMetadata> e : metadata.entrySet()) { if (e.getValue().getStatus() != Status.STORED) { continue; } Sha256Hash hash = hashForStreams.get(e.getKey()); ret.put(hash, e.getKey()); } return ret; }
@Override protected void putMetadataAndHashIndexTask(Transaction t, Map<Long, StreamMetadata> streamIdsToMetadata) { SnapshotsStreamMetadataTable mdTable = tables.getSnapshotsStreamMetadataTable(t); Map<Long, StreamMetadata> prevMetadatas = getMetadata(t, streamIdsToMetadata.keySet()); Map<SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow, StreamMetadata> rowsToStoredMetadata = Maps.newHashMap(); Map<SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow, StreamMetadata> rowsToUnstoredMetadata = Maps.newHashMap(); for (Entry<Long, StreamMetadata> e : streamIdsToMetadata.entrySet()) { long streamId = e.getKey(); StreamMetadata metadata = e.getValue(); StreamMetadata prevMetadata = prevMetadatas.get(streamId); if (metadata.getStatus() == Status.STORED) { if (prevMetadata == null || prevMetadata.getStatus() != Status.STORING) { // This can happen if we cleanup old streams. throw new TransactionFailedRetriableException("Cannot mark a stream as stored that isn't currently storing: " + prevMetadata); } rowsToStoredMetadata.put(SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow.of(streamId), metadata); } else if (metadata.getStatus() == Status.STORING) { // This will prevent two users trying to store the same id. if (prevMetadata != null) { throw new TransactionFailedRetriableException("Cannot reuse the same stream id: " + streamId); } rowsToUnstoredMetadata.put(SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow.of(streamId), metadata); } } putHashIndexTask(t, rowsToStoredMetadata); Map<SnapshotsStreamMetadataTable.SnapshotsStreamMetadataRow, StreamMetadata> rowsToMetadata = Maps.newHashMap(); rowsToMetadata.putAll(rowsToStoredMetadata); rowsToMetadata.putAll(rowsToUnstoredMetadata); mdTable.putMetadata(rowsToMetadata); }