Skip to content

Commit 52ad52f

Browse files
release 2020.2
1 parent 76040f3 commit 52ad52f

23 files changed

Lines changed: 309 additions & 249 deletions

doc/InterferenceManual.pdf

16.9 KB
Binary file not shown.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<groupId>su.interference</groupId>
99
<artifactId>interference</artifactId>
10-
<version>2020.1</version>
10+
<version>2020.2</version>
1111
<packaging>jar</packaging>
1212

1313
<name>interference</name>

src/main/java/su/interference/core/ChunkMap.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ public synchronized void add(Chunk c) {
6464
sorted = false;
6565
}
6666

67+
public synchronized void check() {
68+
for (Map.Entry<Integer, Chunk> entry : hmap.entrySet()) {
69+
Chunk c = entry.getValue();
70+
if (c.getHeader().getPtr() != entry.getKey()) {
71+
throw new RuntimeException("internal cmap check failed");
72+
}
73+
}
74+
}
75+
6776
public synchronized List<Chunk> getChunks() {
6877
return list;
6978
}

src/main/java/su/interference/core/DataChunk.java

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ this software and associated documentation files (the "Software"), to deal in
4343
import java.util.Map;
4444
import java.util.concurrent.atomic.AtomicInteger;
4545

46+
import static su.interference.persistent.Table.SYSTEM_PKG_PREFIX;
47+
4648
/**
4749
* @author Yuriy Glotanov
4850
* @since 1.0
@@ -64,7 +66,6 @@ public class DataChunk implements Chunk {
6466
private Object entity;
6567
private Object undoentity;
6668
private Map<Integer, DataChunk> ics = new HashMap<>();
67-
private DataChunk source;
6869
private UndoChunk uc;
6970
private FrameData uframe;
7071
private boolean terminate;
@@ -199,9 +200,6 @@ public Comparable getId (Field idfield, Session s) throws InvocationTargetExcept
199200
final Id a = f[i].getAnnotation(Id.class);
200201
if (a != null) {
201202
if (sa != null) {
202-
//Method z = c.getMethod("get"+f[i].getName().substring(0,1).toUpperCase()+f[i].getName().substring(1,f[i].getName().length()), null);
203-
//Object v = z.invoke(entity, null);
204-
//id = (Comparable) v;
205203
id = (Comparable) f[i].get(entity);
206204
} else {
207205
Method z = c.getMethod("get" + f[i].getName().substring(0, 1).toUpperCase() + f[i].getName().substring(1, f[i].getName().length()), new Class<?>[]{Session.class});
@@ -212,9 +210,6 @@ public Comparable getId (Field idfield, Session s) throws InvocationTargetExcept
212210
}
213211
} else {
214212
if (sa != null) {
215-
//Method z = c.getMethod("get"+f[i].getName().substring(0,1).toUpperCase()+f[i].getName().substring(1,f[i].getName().length()), null);
216-
//Object v = z.invoke(entity, null);
217-
//id = (Comparable) v;
218213
id = (Comparable) idfield.get(entity);
219214
} else {
220215
Method z = c.getMethod("get" + idfield.getName().substring(0, 1).toUpperCase() + idfield.getName().substring(1, idfield.getName().length()), new Class<?>[]{Session.class});
@@ -357,7 +352,6 @@ public DataChunk (byte[] b, Table t, RowHeader h, DataChunk source) {
357352
this.chunk = b;
358353
this.header = h;
359354
this.state = INIT_STATE;
360-
this.source = source;
361355
this.t = t;
362356
}
363357

@@ -490,15 +484,13 @@ public Object getEntity () {
490484
if (t.isIndex()) {
491485
final ResultSetEntity rsa = (ResultSetEntity) ((Table) this.t).getTableClass().getAnnotation(ResultSetEntity.class);
492486
final DataChunk dc = rsa == null ? (DataChunk) Instance.getInstance().getChunkByPointer(this.getHeader().getFramePtr(), this.getHeader().getFramePtrRowId().getRowPointer()) : this;
493-
dc.setIc(this);
494-
((IndexChunk)o).setDataChunk(dc);
495487
if (dc == null) {
496-
// todo during rframe.IndexFrame.init system directory not yet contains replicated FrameData objects
497-
// final long allocId = Instance.getInstance().getFrameById(this.header.getRowID().getFileId()+this.header.getRowID().getFramePointer()).getAllocId();
498-
// final long allocId2 = Instance.getInstance().getFrameById(this.getHeader().getFramePtr()).getAllocId();
499-
// logger.error("null datachunk found for indexframe allocId = " + allocId + " indexptr allocId = " + allocId2);
488+
// todo during rframe.IndexFrame.init system directory not yet contains replicated FrameData objects
500489
logger.error("null datachunk found");
501490
}
491+
dc.setIc(this);
492+
((IndexChunk)o).setFramePtrRowId(this.getHeader().getFramePtrRowId());
493+
((IndexChunk)o).setDataChunk(dc);
502494
}
503495
if (!t.isNoTran()) {
504496
((EntityContainer) o).setRowId(header.getRowID());
@@ -629,19 +621,15 @@ public DataChunk cloneEntity(Session s) throws InternalException {
629621
return dc_;
630622
}
631623

632-
public DataChunk restore(Frame b, Session s) throws Exception {
633-
if (source == null) {
634-
throw new InternalException();
635-
}
636-
if (!(this.getHeader().getRowID().getFileId() == source.getHeader().getRowID().getFileId() && this.getHeader().getRowID().getFramePointer() == source.getHeader().getRowID().getFramePointer())) {
637-
final long srcFrameId = source.getHeader().getRowID().getFileId() + source.getHeader().getRowID().getFramePointer();
624+
public DataChunk restore(UndoChunk uc) throws Exception {
625+
// second, since we are using a dirty hack with changing the header in a source chunk for rollback his,
626+
// we need to first delete the source chunk in the target block to prevent inconsistency within ChunkMap / chunk headers
627+
if (!(this.getHeader().getRowID().getFileId() == uc.getFile() && this.getHeader().getRowID().getFramePointer() == uc.getFrame())) {
628+
final long srcFrameId = uc.getFile() + uc.getFrame();
638629
final Frame srcFrame = Instance.getInstance().getFrameById(srcFrameId).getFrame();
639-
//todo ???
640-
srcFrame.removeChunk(source.getHeader().getRowID().getRowPointer(), null, false);
630+
srcFrame.removeChunk(uc.getPtr(), null, true);
641631
}
642-
source.setHeader(this.getHeader());
643-
source.updateEntity(this.getEntity());
644-
return source;
632+
return this;
645633
}
646634

647635
private byte[] getBytes(Field f, Object o) throws IllegalAccessException, UnsupportedEncodingException, ClassNotFoundException, InternalException, InstantiationException {
@@ -666,15 +654,11 @@ public void setHeader(Header header) {
666654

667655
//lock mechanism
668656

669-
private synchronized DataChunk insertUC (FrameData cb, UndoChunk uc, Session s, LLT llt) throws Exception {
657+
private synchronized DataChunk insertUC (UndoChunk uc, Session s, LLT llt) throws Exception {
670658
final WaitFrame ubw = s.getTransaction().getAvailableFrame(uc, true);
671659
final FrameData ub = ubw.getBd();
672660
if (ub == null) {
673-
//s.getTransaction().createUndoFrames(s);
674-
//ub = s.getTransaction().getAvailableFrame(uc, true);
675-
//if (ub == null) {
676-
throw new InternalException();
677-
//}
661+
throw new InternalException();
678662
}
679663

680664
final DataChunk dc = new DataChunk(uc, s);
@@ -685,10 +669,8 @@ private synchronized DataChunk insertUC (FrameData cb, UndoChunk uc, Session s,
685669
s.getTransaction().setNewLB(ub, nb, false);
686670
nb.getDataFrame().insertChunk(dc, s, true, llt);
687671
dc.uframe = nb;
688-
//s.getTransaction().storeFrame(cb, nb, 0, s, llt);
689672
} else {
690673
dc.uframe = ub;
691-
//s.getTransaction().storeFrame(cb, ub, 0, s, llt);
692674
}
693675
ubw.release();
694676
return dc;
@@ -739,25 +721,11 @@ public synchronized DataChunk lock (Session s, LLT llt) throws Exception {
739721
this.getHeader().setTran(s.getTransaction());
740722
((EntityContainer)o).setTran(s.getTransaction());
741723

742-
final FrameData bd = Instance.getInstance().getFrameById(this.getHeader().getRowID().getFileId() + this.getHeader().getRowID().getFramePointer());
743724
final DataChunk cc = this.cloneEntity(s);
744725
cc.getHeader().setTran(s.getTransaction());
745726
final RowId rw = this.getHeader().getRowID();
746727
uc = new UndoChunk(cc, s.getTransaction(), rw.getFileId(), rw.getFramePointer(), rw.getRowPointer());
747-
return insertUC(bd, uc, s, llt);
748-
}
749-
750-
protected synchronized void undo(Session s, LLT llt) throws Exception {
751-
if (s.getTransaction().getTransId() != this.getHeader().getTran().getTransId()) {
752-
throw new InternalException();
753-
} else {
754-
final FrameData bd = Instance.getInstance().getFrameById(this.getHeader().getRowID().getFileId() + this.getHeader().getRowID().getFramePointer());
755-
final DataChunk cc = this.cloneEntity(s);
756-
cc.getHeader().setTran(s.getTransaction());
757-
final RowId rw = this.getHeader().getRowID();
758-
uc = new UndoChunk(cc, s.getTransaction(), rw.getFileId(), rw.getFramePointer(), rw.getRowPointer());
759-
insertUC(bd, uc, s, llt);
760-
}
728+
return insertUC(uc, s, llt);
761729
}
762730

763731
public FrameData getUframe() {
@@ -777,8 +745,48 @@ public void setIc(DataChunk ic) {
777745
this.ics.put(t_.getObjectId(), ic);
778746
}
779747

780-
public Map<Integer, DataChunk> getIcs() {
781-
return this.ics;
748+
public void clearIcs() {
749+
this.ics.clear();
750+
}
751+
752+
protected void cleanUpIcs() {
753+
for (Map.Entry<Integer, DataChunk> entry : this.ics.entrySet()) {
754+
final IndexChunk ic = (IndexChunk) entry.getValue().getEntity();
755+
ic.setDataChunk(null);
756+
}
757+
}
758+
759+
public DataChunk getIc(IndexDescript ids, Session s) throws Exception {
760+
final Table ixt = Instance.getInstance().getTableByName(SYSTEM_PKG_PREFIX + ids.getName());
761+
final DataChunk ic = this.ics.get(ixt.getObjectId());
762+
if (ic == null) {
763+
final ValueSet key = this.getValueByColumnName(ids.getColumns(), s);
764+
final DataChunk ic_ = ixt.getObjectByKey(key, s);
765+
if (ic_ != null) {
766+
this.ics.put(ixt.getObjectId(), ic_);
767+
return ic_;
768+
} else {
769+
throw new RuntimeException("Unable to retrieve index chunk: " + ids.getName());
770+
}
771+
}
772+
return ic;
773+
}
774+
775+
public ValueSet getValueByColumnName(String[] columns, Session s) throws Exception {
776+
final Object o = this.getEntity();
777+
final Class c = o.getClass();
778+
final SystemEntity sa = (SystemEntity)c.getAnnotation(SystemEntity.class);
779+
final List<Object> res = new ArrayList<>();
780+
for (String name : columns) {
781+
if (sa != null) {
782+
final Method z = c.getMethod("get" + name.substring(0, 1).toUpperCase() + name.substring(1, name.length()), null);
783+
res.add(z.invoke(o, null));
784+
} else {
785+
final Method z = c.getMethod("get" + name.substring(0, 1).toUpperCase() + name.substring(1, name.length()), new Class<?>[]{Session.class});
786+
res.add(z.invoke(o, new Object[]{s}));
787+
}
788+
}
789+
return new ValueSet(res.toArray(new Object[]{}));
782790
}
783791

784792
private byte[] getBytesFromHexString(String s) {

src/main/java/su/interference/core/DataFrame.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,33 @@ public DataFrame(FrameData bd, Table t) throws InternalException {
4848
super (bd, t);
4949
}
5050

51-
public DataFrame(int file, long pointer, int size, FrameData bd, Table t, Class c) throws Exception {
51+
public DataFrame(int file, long pointer, int size, FrameData bd, Table t, Class c, List<FrameData> uframes) throws Exception {
5252
super(null, file, pointer, size, bd, t, c);
5353

54+
Map<Integer, UndoChunk> ucs = new HashMap<>();
55+
for (FrameData uframe : uframes) {
56+
final DataFrame uf = uframe.getDataFrame();
57+
for (Chunk udc : uf.getChunks()) {
58+
UndoChunk uc = (UndoChunk) udc.getEntity();
59+
final long frameId = file + pointer;
60+
final long frameId_ = uc.getFile() + uc.getFrame();
61+
if (frameId == frameId_) {
62+
ucs.put(uc.getPtr(), uc);
63+
}
64+
}
65+
}
66+
5467
int ptr = FRAME_HEADER_SIZE;
5568
final ByteString bs = new ByteString(this.b);
5669
while (ptr<this.b.length) {
5770
if (this.b.length>=ptr+ROW_HEADER_SIZE) {
5871
final RowHeader h = new RowHeader(bs.substring(ptr, ptr+ROW_HEADER_SIZE), this.getFile(), this.getPointer());
5972
if ((h.getPtr()>0)&&(h.getLen()>0)) {
60-
data.add(new DataChunk(bs.substring(ptr, ptr+ROW_HEADER_SIZE+h.getLen()), this.getFile(), this.getPointer(), ROW_HEADER_SIZE, this.getDataObject(), this.getEntityClass()));
73+
final DataChunk dc = new DataChunk(bs.substring(ptr, ptr+ROW_HEADER_SIZE+h.getLen()), this.getFile(), this.getPointer(), ROW_HEADER_SIZE, this.getDataObject(), this.getEntityClass());
74+
if (ucs.get(dc.getHeader().getPtr()) != null) {
75+
dc.setUndoChunk(ucs.get(dc.getHeader().getPtr()));
76+
}
77+
data.add(dc);
6178
ptr = ptr + ROW_HEADER_SIZE + h.getLen();
6279
} else {
6380
ptr = this.b.length;

src/main/java/su/interference/core/Frame.java

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ public synchronized int updateChunk(DataChunk chunk, Object o, Session s, LLT ll
453453
}
454454
chunk.setNormalState();
455455
final byte[] ncb = chunk.getChunk();
456+
// chunk.getHeader().setState(Header.RECORD_UPDATED_STATE);
456457
chunk.getHeader().setLen(ncb.length);
457458
chunk.getHeader().setTran(tran);
458459
final int newlen = chunk.getBytesAmount();
@@ -470,9 +471,6 @@ public synchronized void deleteChunk (int ptr, Session s, LLT llt) {
470471
throw new CannotAccessToDeletedRecord();
471472
}
472473
final Header header = chunk.getHeader();
473-
if (header.getState() == Header.RECORD_LOCKED_STATE) {
474-
throw new CannotAccessToLockedRecord();
475-
}
476474
if (header.getLltId() < sync) {
477475
final ByteString sc = new ByteString();
478476
sc.append(chunk.getHeader().getHeader());
@@ -489,6 +487,10 @@ public synchronized List<Chunk> getChunks() {
489487
return data.getChunks();
490488
}
491489

490+
public synchronized boolean checkChunk(int ptr) {
491+
return data.getByPtr(ptr) != null;
492+
}
493+
492494
public synchronized void removeChunk (int ptr, LLT llt, boolean ignore) {
493495
if (!this.isLocal()) {
494496
throw new CannotAccessToForeignRecord();
@@ -519,8 +521,8 @@ public synchronized ArrayList<Chunk> getFrameChunks (Session s) {
519521
if (dataObject==null) {
520522
dataObject = Instance.getInstance().getTableById(this.objectId);
521523
}
522-
if (dataObject.isNoTran() || s.isStream()) {
523524

525+
if (dataObject.isNoTran() || s.isStream()) {
524526
final int streamptr = s.isStream() ? s.streamFramePtr(this) : 0;
525527

526528
for (Chunk c : data.getChunks()) {
@@ -535,47 +537,41 @@ public synchronized ArrayList<Chunk> getFrameChunks (Session s) {
535537
s.streamFramePtr(this, rowCntr);
536538
}
537539

538-
} else { //if (local()) {
539-
540+
} else {
540541
final long tr = s.getTransaction().getTransId();
541542
final long mtran = s.getTransaction().getMTran();
542543

543544
// read frame records
544545
for (Chunk c : data.getChunks()) {
545-
Header h = c.getHeader();
546-
if (h.getState()==Header.RECORD_NORMAL_STATE) {
547-
if (c.getUndoChunk() != null && c.getHeader().getTran().getCid() == 0) { //updated chunk in live transaction
548-
res.add(c);
546+
final Header h = c.getHeader();
547+
if (c.getUndoChunk() != null && h.getTran() != null) {
548+
if (h.getState() == Header.RECORD_DELETED_STATE) {
549+
if ((tr != h.getTran().getTransId()) && (h.getTran().getCid() == 0 || h.getTran().getCid() > mtran)) {
550+
res.add(c);
551+
}
549552
} else {
553+
res.add(c);
554+
}
555+
} else {
556+
if (h.getState() == Header.RECORD_NORMAL_STATE) {
550557
if (h.getTran() == null) {
551558
res.add(c);
552559
} else {
553560
if ((tr == h.getTran().getTransId()) || (h.getTran().getCid() > 0 && h.getTran().getCid() <= mtran)) {
554561
res.add(c);
555-
} else {
556-
System.out.println("ooooops!!!");
557562
}
558563
}
559564
}
560565
}
561-
if (h.getState() == Header.RECORD_DELETED_STATE) {
562-
if (h.getTran()!=null) {
563-
if ((tr != h.getTran().getTransId()) && (h.getTran().getCid() == 0 || h.getTran().getCid() > mtran)) {
564-
res.add(c);
565-
} else {
566-
System.out.println("ooooops!!!");
567-
}
568-
} else {
569-
System.out.println("ooooops!!!");
570-
}
571-
}
572566
}
573567
}
574568

575569
return res;
576570
}
577571

578572
public synchronized void rollbackTransaction(Transaction tran, ArrayList<FrameData> ubs, Session s) throws InterruptedException {
573+
data.check();
574+
579575
//rollback inserted records
580576
final ArrayList<Integer> r = new ArrayList<>();
581577
for (Chunk c : data.getChunks()) {
@@ -594,9 +590,10 @@ public synchronized void rollbackTransaction(Transaction tran, ArrayList<FrameDa
594590
for (FrameData ub : ubs) {
595591
for (Chunk c : ub.getDataFrame().getChunks()) {
596592
final UndoChunk uc = (UndoChunk)c.getEntity();
593+
final int ucfile = uc.getDataChunk().getHeader().getRowID().getFileId();
597594
final long frameptr = uc.getDataChunk().getHeader().getRowID().getFramePointer();
598-
if (uc.getTransId() == tran.getTransId() && uc.getFile() == this.file && frameptr == this.pointer) {
599-
data.add(uc.getDataChunk().restore(this, s));
595+
if (uc.getTransId() == tran.getTransId() && ucfile == this.file && frameptr == this.pointer) {
596+
data.add(uc.getDataChunk().restore(uc));
600597
}
601598
}
602599
}
@@ -641,6 +638,12 @@ public boolean isLocal() {
641638
return this.file+this.pointer == this.allocFile+this.allocPointer;
642639
}
643640

641+
public void cleanUpIcs() {
642+
for (Chunk c : this.data.getChunks()) {
643+
((DataChunk) c).cleanUpIcs();
644+
}
645+
}
646+
644647
public long getPtr() {
645648
return pointer+file;
646649
}

src/main/java/su/interference/core/Header.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ this software and associated documentation files (the "Software"), to deal in
3333

3434
public interface Header {
3535

36-
public static final int RECORD_NORMAL_STATE = 1;
37-
public static final int RECORD_LOCKED_STATE = 2;
38-
public static final int RECORD_DELETED_STATE = 3;
36+
int RECORD_NORMAL_STATE = 1;
37+
int RECORD_UPDATED_STATE = 2;
38+
int RECORD_DELETED_STATE = 3;
3939

4040
Transaction getTran ();
4141
int getState();

0 commit comments

Comments
 (0)