use of jetbrains.exodus.core.dataStructures.Pair in project xodus by JetBrains.
the class EnvironmentTest method createReaderWriter.
private Pair<DataReader, DataWriter> createReaderWriter(String subfolder) throws IOException {
final File parent = getEnvDirectory();
File child = subfolders.get(subfolder);
if (child == null) {
child = new File(parent, subfolder);
if (child.exists())
throw new IOException("SubDirectory already exists " + subfolder);
if (!child.mkdirs()) {
throw new IOException("Failed to create directory " + subfolder + " for tests.");
}
subfolders.put(subfolder, child);
}
return new Pair<DataReader, DataWriter>(new FileDataReader(child, 16), new FileDataWriter(child));
}
use of jetbrains.exodus.core.dataStructures.Pair in project xodus by JetBrains.
the class TreeCursorDuplicatesTest method test_xd_347_like.
@Test
public void test_xd_347_like() {
tm = createMutableTree(true, 1);
final int count = 20000;
long value = 0;
final LongHashMap<LongHashSet> values = new LongHashMap<>();
final Random rnd = new Random();
for (int i = 0; i < count; ++i, ++value) {
if (i > count / 2) {
final Pair<Long, LongHashSet>[] pair = new Pair[1];
values.forEachEntry(new ObjectProcedure<Map.Entry<Long, LongHashSet>>() {
@Override
public boolean execute(Map.Entry<Long, LongHashSet> object) {
pair[0] = new Pair<>(object.getKey(), object.getValue());
return false;
}
});
final Pair<Long, LongHashSet> p = pair[0];
final LongHashSet oldSet = p.getSecond();
final long oldValue = oldSet.iterator().nextLong();
final Long oldKey = p.getFirst();
try (ITreeCursor cursor = tm.openCursor()) {
if (!cursor.getSearchBoth(key(oldKey), value(oldValue))) {
Assert.assertTrue(cursor.getSearchBoth(key(oldKey), value(oldValue)));
}
cursor.deleteCurrent();
}
Assert.assertTrue(oldSet.remove(oldValue));
if (oldSet.isEmpty()) {
Assert.assertEquals(oldSet, values.remove(oldKey));
}
}
final long key = System.currentTimeMillis() + rnd.nextInt(count / 10);
LongHashSet keyValues = values.get(key);
if (keyValues == null) {
keyValues = new LongHashSet();
values.put(key, keyValues);
}
Assert.assertTrue(keyValues.add(value));
tm.put(key(key), value(value));
}
}
use of jetbrains.exodus.core.dataStructures.Pair in project xodus by JetBrains.
the class PersistentEntityStoreImpl method getInPlaceBlobStream.
@Nullable
private Pair<Long, InputStream> getInPlaceBlobStream(@NotNull final PersistentStoreTransaction txn, @NotNull final PersistentEntity entity, @NotNull final String blobName) throws IOException {
final Pair<Long, ByteIterator> blobInfo = getBlobHandleAndValue(txn, entity, blobName);
if (blobInfo == null) {
return null;
}
final long blobHandle = blobInfo.getFirst();
if (blobHandle == EMPTY_BLOB_HANDLE) {
return new Pair<>(blobHandle, null);
}
if (blobHandle == IN_PLACE_BLOB_HANDLE) {
final ByteIterator valueIterator = blobInfo.getSecond();
final int size = (int) CompressedUnsignedLongByteIterable.getLong(valueIterator);
return new Pair<Long, InputStream>(blobHandle, new ByteArraySizedInputStream(ByteIterableBase.readIterator(valueIterator, size)));
}
return new Pair<>(blobHandle, txn.getBlobStream(blobHandle));
}
use of jetbrains.exodus.core.dataStructures.Pair in project xodus by JetBrains.
the class PersistentEntityStoreImpl method getBlobHandleAndValue.
@Nullable
Pair<Long, ByteIterator> getBlobHandleAndValue(@NotNull final PersistentStoreTransaction txn, @NotNull final PersistentEntity entity, @NotNull final String blobName) {
final int blobId = getPropertyId(txn, blobName, false);
if (blobId < 0) {
return null;
}
final ByteIterable valueEntry = getRawValue(txn, entity.getId(), blobId, blobDataGetter);
if (valueEntry == null) {
return null;
}
final ByteIterator valueIterator = valueEntry.iterator();
return new Pair<>(LongBinding.readCompressed(valueIterator), valueIterator);
}
use of jetbrains.exodus.core.dataStructures.Pair in project xodus by JetBrains.
the class PersistentEntityStoreRefactorings method refactorMakeLinkTablesConsistent.
void refactorMakeLinkTablesConsistent(final Store internalSettings) {
store.executeInReadonlyTransaction(new StoreTransactionalExecutable() {
@Override
public void execute(@NotNull final StoreTransaction tx) {
final PersistentStoreTransaction txn = (PersistentStoreTransaction) tx;
for (final String entityType : store.getEntityTypes(txn)) {
if (logger.isInfoEnabled()) {
logger.info("Refactoring making links' tables consistent for [" + entityType + ']');
}
runReadonlyTransactionSafeForEntityType(entityType, new Runnable() {
@Override
public void run() {
final Collection<Pair<ByteIterable, ByteIterable>> redundantLinks = new ArrayList<>();
final Collection<Pair<ByteIterable, ByteIterable>> deleteLinks = new ArrayList<>();
final int entityTypeId = store.getEntityTypeId(txn, entityType, false);
final LinksTable linksTable = store.getLinksTable(txn, entityTypeId);
final Transaction envTxn = txn.getEnvironmentTransaction();
final LongSet all = new PackedLongHashSet();
final LongSet linkFilter = new PackedLongHashSet();
try (Cursor cursor = store.getEntitiesIndexCursor(txn, entityTypeId)) {
while (cursor.getNext()) {
all.add(LongBinding.compressedEntryToLong(cursor.getKey()));
}
}
final IntHashSet redundantLinkTypes = new IntHashSet();
final IntHashSet deletedLinkTypes = new IntHashSet();
final IntHashSet deletedLinkIds = new IntHashSet();
try (Cursor cursor = linksTable.getFirstIndexCursor(envTxn)) {
while (cursor.getNext()) {
final ByteIterable first = cursor.getKey();
final ByteIterable second = cursor.getValue();
LinkValue linkValue = null;
final long localId = LongBinding.compressedEntryToLong(first);
if (!all.contains(localId)) {
try {
linkValue = LinkValue.entryToLinkValue(second);
deletedLinkTypes.add(linkValue.getEntityId().getTypeId());
deletedLinkIds.add(linkValue.getLinkId());
} catch (ArrayIndexOutOfBoundsException ignore) {
}
do {
deleteLinks.add(new Pair<>(first, second));
} while (cursor.getNextDup());
continue;
} else {
linkFilter.add((first.hashCode() << 31L) + second.hashCode());
}
if (linkValue == null) {
try {
linkValue = LinkValue.entryToLinkValue(second);
} catch (ArrayIndexOutOfBoundsException ignore) {
deleteLinks.add(new Pair<>(first, second));
}
}
if (linkValue != null) {
final EntityId targetEntityId = linkValue.getEntityId();
// if target doesn't exist
if (store.getLastVersion(txn, targetEntityId) < 0) {
deletedLinkTypes.add(targetEntityId.getTypeId());
deletedLinkIds.add(linkValue.getLinkId());
deleteLinks.add(new Pair<>(first, second));
continue;
} else {
linkFilter.add((first.hashCode() << 31L) + second.hashCode());
}
if (!linksTable.contains2(envTxn, first, second)) {
redundantLinkTypes.add(targetEntityId.getTypeId());
redundantLinks.add(new Pair<>(first, second));
}
}
}
}
if (!redundantLinks.isEmpty()) {
store.getEnvironment().executeInTransaction(new TransactionalExecutable() {
@Override
public void execute(@NotNull final Transaction txn) {
for (final Pair<ByteIterable, ByteIterable> badLink : redundantLinks) {
linksTable.put(txn, badLink.getFirst(), badLink.getSecond());
}
}
});
if (logger.isInfoEnabled()) {
logger.info(redundantLinks.size() + " missing links found for [" + entityType + ']');
}
redundantLinks.clear();
}
try (Cursor cursor = linksTable.getSecondIndexCursor(envTxn)) {
while ((cursor.getNext())) {
final ByteIterable second = cursor.getKey();
final ByteIterable first = cursor.getValue();
if (!linkFilter.contains((first.hashCode() << 31L) + second.hashCode())) {
if (!linksTable.contains(envTxn, first, second)) {
redundantLinks.add(new Pair<>(first, second));
}
}
}
}
final int redundantLinksSize = redundantLinks.size();
final int deleteLinksSize = deleteLinks.size();
if (redundantLinksSize > 0 || deleteLinksSize > 0) {
store.getEnvironment().executeInTransaction(new TransactionalExecutable() {
@Override
public void execute(@NotNull final Transaction txn) {
for (final Pair<ByteIterable, ByteIterable> redundantLink : redundantLinks) {
deletePair(linksTable.getSecondIndexCursor(txn), redundantLink.getFirst(), redundantLink.getSecond());
}
for (final Pair<ByteIterable, ByteIterable> deleteLink : deleteLinks) {
deletePair(linksTable.getFirstIndexCursor(txn), deleteLink.getFirst(), deleteLink.getSecond());
deletePair(linksTable.getSecondIndexCursor(txn), deleteLink.getSecond(), deleteLink.getFirst());
}
}
});
if (logger.isInfoEnabled()) {
if (redundantLinksSize > 0) {
final ArrayList<String> redundantLinkTypeNames = new ArrayList<>(redundantLinkTypes.size());
for (final int typeId : redundantLinkTypes) {
redundantLinkTypeNames.add(store.getEntityType(txn, typeId));
}
logger.info(redundantLinksSize + " redundant links found and fixed for [" + entityType + "] and targets: " + redundantLinkTypeNames);
}
if (deleteLinksSize > 0) {
final ArrayList<String> deletedLinkTypeNames = new ArrayList<>(deletedLinkTypes.size());
for (final int typeId : deletedLinkTypes) {
try {
final String entityTypeName = store.getEntityType(txn, typeId);
deletedLinkTypeNames.add(entityTypeName);
} catch (Throwable t) {
// ignore
}
}
final ArrayList<String> deletedLinkIdsNames = new ArrayList<>(deletedLinkIds.size());
for (final int typeId : deletedLinkIds) {
try {
final String linkName = store.getLinkName(txn, typeId);
deletedLinkIdsNames.add(linkName);
} catch (Throwable t) {
// ignore
}
}
logger.info(deleteLinksSize + " phantom links found and fixed for [" + entityType + "] and targets: " + deletedLinkTypeNames);
logger.info("Link types: " + deletedLinkIdsNames);
}
}
}
// reset link null indices
Settings.delete(internalSettings, "Link null-indices present");
}
});
}
}
});
}
Aggregations