mirror of
https://github.com/usatiuk/dhfs.git
synced 2025-10-28 20:47:49 +01:00
basic object deletion
This commit is contained in:
@@ -3,11 +3,13 @@ package com.usatiuk.objects.alloc.test;
|
||||
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||
import org.jboss.shrinkwrap.api.spec.JavaArchive;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
import io.quarkus.test.QuarkusDevModeTest;
|
||||
|
||||
@Disabled
|
||||
public class ObjectsAllocDevModeTest {
|
||||
|
||||
// Start hot reload (DevMode) test with your extension loaded
|
||||
|
||||
@@ -6,9 +6,11 @@ import jakarta.inject.Inject;
|
||||
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||
import org.jboss.shrinkwrap.api.spec.JavaArchive;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
@Disabled
|
||||
public class ObjectsAllocTest {
|
||||
|
||||
// Start unit test with your extension loaded
|
||||
|
||||
@@ -24,6 +24,11 @@ public class CurrentTransaction implements Transaction {
|
||||
return transactionManager.current().getObject(type, key, strategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteObject(JObjectKey key) {
|
||||
transactionManager.current().deleteObject(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends JData> void putObject(JData obj) {
|
||||
transactionManager.current().putObject(obj);
|
||||
|
||||
@@ -196,7 +196,8 @@ public class JObjectManager {
|
||||
|
||||
var toFlush = new LinkedList<TxRecord.TxObjectRecordWrite<?>>();
|
||||
var toPut = new LinkedList<TxRecord.TxObjectRecordNew<?>>();
|
||||
var toLock = new ArrayList<TransactionObject<?>>();
|
||||
var toDelete = new LinkedList<JObjectKey>();
|
||||
var toLock = new ArrayList<JObjectKey>();
|
||||
var dependencies = new LinkedList<TransactionObject<?>>();
|
||||
|
||||
Log.trace("Committing transaction " + tx.getId());
|
||||
@@ -214,12 +215,16 @@ public class JObjectManager {
|
||||
toFlush.add(copy);
|
||||
}
|
||||
case TxRecord.TxObjectRecordOptimistic<?> copy -> {
|
||||
toLock.add(copy.original());
|
||||
toLock.add(copy.original().data().getKey());
|
||||
toFlush.add(copy);
|
||||
}
|
||||
case TxRecord.TxObjectRecordNew<?> created -> {
|
||||
toPut.add(created);
|
||||
}
|
||||
case TxRecord.TxObjectRecordDeleted deleted -> {
|
||||
toLock.add(deleted.key());
|
||||
toDelete.add(deleted.key());
|
||||
}
|
||||
default -> throw new IllegalStateException("Unexpected value: " + entry);
|
||||
}
|
||||
}
|
||||
@@ -231,7 +236,7 @@ public class JObjectManager {
|
||||
// TODO: Check this
|
||||
}
|
||||
case ReadTrackingObjectSource.TxReadObjectSome<?>(var obj) -> {
|
||||
toLock.add(obj);
|
||||
toLock.add(obj.data().getKey());
|
||||
dependencies.add(obj);
|
||||
}
|
||||
default -> throw new IllegalStateException("Unexpected value: " + entry);
|
||||
@@ -240,28 +245,23 @@ public class JObjectManager {
|
||||
|
||||
toLock.sort(Comparator.comparingInt(System::identityHashCode));
|
||||
|
||||
for (var record : toLock) {
|
||||
Log.trace("Locking " + record.toString());
|
||||
for (var key : toLock) {
|
||||
Log.trace("Locking " + key.toString());
|
||||
|
||||
var got = getLocked(record.data().getClass(), record.data().getKey(), true);
|
||||
var got = getLocked(JData.class, key, true);
|
||||
|
||||
if (got == null) {
|
||||
throw new IllegalStateException("Object " + record.data().getKey() + " not found");
|
||||
throw new IllegalStateException("Object " + key + " not found");
|
||||
}
|
||||
|
||||
toUnlock.add(got.wrapper().lock.writeLock()::unlock);
|
||||
|
||||
if (got.obj() != record.data()) {
|
||||
throw new IllegalStateException("Object changed during transaction: " + got.obj() + " vs " + record.data());
|
||||
}
|
||||
}
|
||||
|
||||
for (var dep : dependencies) {
|
||||
Log.trace("Checking dependency " + dep.toString());
|
||||
var current = _objects.get(dep.data().getKey()).get();
|
||||
|
||||
// Checked above
|
||||
assert current == dep.data();
|
||||
if (current == null) continue; // FIXME? Does this matter much for deletion
|
||||
|
||||
if (current.getVersion() >= tx.getId()) {
|
||||
throw new IllegalStateException("Serialization hazard: " + current.getVersion() + " vs " + tx.getId());
|
||||
@@ -312,7 +312,11 @@ public class JObjectManager {
|
||||
|
||||
Log.tracef("Committing transaction %d to storage", tx.getId());
|
||||
|
||||
objectStorage.commitTx(new SimpleTxManifest(written.stream().map(JData::getKey).toList(), Collections.emptyList()));
|
||||
objectStorage.commitTx(new SimpleTxManifest(written.stream().map(JData::getKey).toList(), toDelete));
|
||||
|
||||
for (var del : toDelete) {
|
||||
_objects.remove(del);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.error("Error when committing transaction", t);
|
||||
throw t;
|
||||
|
||||
@@ -13,6 +13,8 @@ public interface Transaction {
|
||||
|
||||
<T extends JData> void putObject(JData obj);
|
||||
|
||||
void deleteObject(JObjectKey key);
|
||||
|
||||
default <T extends JData> Optional<T> getObject(Class<T> type, JObjectKey key) {
|
||||
return getObject(type, key, LockingStrategy.OPTIMISTIC);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,11 @@ public class TransactionFactoryImpl implements TransactionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteObject(JObjectKey key) {
|
||||
_objects.put(key, new TxRecord.TxObjectRecordDeleted(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putObject(JData obj) {
|
||||
if (_objects.containsKey(obj.getKey())) {
|
||||
|
||||
@@ -31,6 +31,13 @@ public class TxRecord {
|
||||
}
|
||||
}
|
||||
|
||||
public record TxObjectRecordDeleted(JObjectKey key) implements TxObjectRecord<JData> {
|
||||
@Override
|
||||
public JData getIfStrategyCompatible(JObjectKey key, LockingStrategy strategy) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public record TxObjectRecordCopyLock<T extends JData>(TransactionObject<T> original,
|
||||
ChangeTrackingJData<T> copy)
|
||||
implements TxObjectRecordWrite<T> {
|
||||
|
||||
@@ -46,6 +46,37 @@ public class ObjectsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void createDeleteObject() {
|
||||
{
|
||||
txm.begin();
|
||||
var newParent = alloc.create(Parent.class, new JObjectKey("Parent"));
|
||||
newParent.setLastName("John");
|
||||
curTx.putObject(newParent);
|
||||
txm.commit();
|
||||
}
|
||||
|
||||
{
|
||||
txm.begin();
|
||||
var parent = curTx.getObject(Parent.class, new JObjectKey("Parent")).orElse(null);
|
||||
Assertions.assertEquals("John", parent.getLastName());
|
||||
txm.commit();
|
||||
}
|
||||
|
||||
{
|
||||
txm.begin();
|
||||
curTx.deleteObject(new JObjectKey("Parent"));
|
||||
txm.commit();
|
||||
}
|
||||
|
||||
{
|
||||
txm.begin();
|
||||
var parent = curTx.getObject(Parent.class, new JObjectKey("Parent")).orElse(null);
|
||||
Assertions.assertNull(parent);
|
||||
txm.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void createCreateObject() {
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user