Skip to content

Commit

Permalink
Support for CAD3 Dense Record types
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Oct 12, 2024
1 parent 9577f5d commit 1ef0fef
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 65 deletions.
44 changes: 27 additions & 17 deletions convex-core/src/main/java/convex/core/data/ACAD3Record.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import convex.core.data.util.BlobBuilder;
import convex.core.exceptions.InvalidDataException;
import convex.core.lang.RT;
import convex.core.util.Utils;

/**
* Abstract base class for non-CVM CAD3 Records values. These look like countable sequences to CVM code.
Expand All @@ -11,43 +12,52 @@
*/
public abstract class ACAD3Record extends ASequence<ACell> {

public ACAD3Record(long count) {
super(count);
}
protected final byte tag;

@Override
public int estimatedEncodingSize() {
return encoding.size();
protected ACAD3Record(byte tag,long count) {
super(count);
this.tag=tag;
}

@Override
public void validateCell() throws InvalidDataException {
// TODO Auto-generated method stub
byte cat=Tag.category(tag);
switch (cat) {
case Tag.DENSE_RECORD_BASE:
case Tag.SPARSE_RECORD_BASE:
break; // seems OK
default: throw new InvalidDataException("Bad tag for CAD3 Record: 0x"+Utils.toHexString(tag),this);
}
}

@Override
public byte getTag() {
return encoding.byteAt(0);
return tag;
}

@Override
public boolean equals(ACell a) {
if (a==null) return false;
if (a.getTag()!=getTag()) return false;
if (a.getTag()!=tag) return false;
return encoding.equals(a.getEncoding());
}

@Override
public int encode(byte[] bs, int pos) {
encoding.getBytes(bs, pos);
return pos+encoding.size();
bs[pos++]=tag;
return encodeRaw(bs,pos);
}


// subclasses must implement getRefCount and getRef

@Override
public int encodeRaw(byte[] bs, int pos) {
encoding.slice(1).getBytes(bs, pos);
return pos+encoding.size()-1;
}
public abstract int getRefCount();

@Override
public abstract Ref<ACell> getRef(int i);

@Override
public abstract ACell updateRefs(IRefFunction func);

@Override
public boolean isCanonical() {
Expand Down
2 changes: 1 addition & 1 deletion convex-core/src/main/java/convex/core/data/ACell.java
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ public AString toCVMString(long limit) {
*
* @return The cached blob for this cell, or null if not yet available.
*/
public Blob cachedEncoding() {
public final Blob cachedEncoding() {
return encoding;
}

Expand Down
2 changes: 0 additions & 2 deletions convex-core/src/main/java/convex/core/data/AMapEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ public final V setValue(V value) {

@Override
public abstract boolean isCanonical();



@Override
public AVector<ACell> append(ACell value) {
Expand Down
4 changes: 2 additions & 2 deletions convex-core/src/main/java/convex/core/data/ASequence.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

/**
* Abstract base class for concrete sequential data structure (immutable persistent lists and vectors etc.)
*
* Implements standard java.util.List interface
*
* @param <T> Type of list elements
*/
Expand Down Expand Up @@ -169,8 +171,6 @@ public boolean containsKey(ACell key) {
return false;
}



/**
* Gets the element Ref at the specified index
*
Expand Down
116 changes: 77 additions & 39 deletions convex-core/src/main/java/convex/core/data/DenseRecord.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,46 @@
import java.util.function.Function;

import convex.core.data.type.AType;
import convex.core.data.type.Types;
import convex.core.exceptions.BadFormatException;

public class DenseRecord extends ACAD3Record {

protected AVector<ACell> data;
protected final AVector<ACell> data;

public DenseRecord(long count) {
super(count);
protected DenseRecord(byte tag, AVector<ACell> data) {
super(tag,data.count());
this.data=data;
}

public static DenseRecord create(int tag,AVector<ACell> data) {
if (data==null) return null;
if (Tag.category(tag)!=Tag.DENSE_RECORD_BASE) return null; // not an extension value

return new DenseRecord((byte)tag,data);
}

@Override
public int estimatedEncodingSize() {
return data.estimatedEncodingSize();
}

@Override
public int encodeRaw(byte[] bs, int pos) {
return data.encodeRaw(bs, pos);
}

public static DenseRecord read(byte tag, Blob b, int pos) throws BadFormatException {
AVector<ACell> data=Vectors.read(b, pos);

Blob enc=data.cachedEncoding();
data.attachEncoding(null); // clear invalid encoding

DenseRecord dr=create(tag,data);
if ((enc!=null)&&(enc.byteAt(0)==tag)) {
dr.attachEncoding(enc);
}
return dr;
}

@Override
Expand All @@ -34,112 +67,117 @@ public long longLastIndexOf(ACell value) {
return data.longLastIndexOf(value);
}

@SuppressWarnings("unchecked")
@Override
public <R extends ACell> ASequence<R> map(Function<? super ACell, ? extends R> mapper) {
// TODO Auto-generated method stub
return null;
AVector<ACell> rdata=data.map(mapper);
return (ASequence<R>) rdata;
}

@Override
public void forEach(Consumer<? super ACell> action) {
// TODO Auto-generated method stub

data.forEach(action);
}

@Override
public void visitElementRefs(Consumer<Ref<ACell>> f) {
// TODO Auto-generated method stub

data.visitElementRefs(f);
}

@Override
public ASequence<ACell> concat(ASequence<? extends ACell> vals) {
// TODO Auto-generated method stub
return null;
return data.concat(vals);
}

@Override
public ASequence<ACell> next() {
// TODO Auto-generated method stub
return null;
return data.next();
}

@Override
public ASequence<ACell> empty() {
// TODO Auto-generated method stub
return null;
return Vectors.empty();
}

@Override
public ACell get(long index) {
// TODO Auto-generated method stub
return null;
return data.get(index);
}

@Override
public Ref<ACell> getElementRef(long index) {
// TODO Auto-generated method stub
return null;
return data.getElementRef(index);
}

@Override
public ASequence<ACell> assoc(long i, ACell value) {
// TODO Auto-generated method stub
return null;
AVector<ACell> newData=data.assoc(i, value);
return newData;
}

@Override
public ASequence<ACell> conj(ACell value) {
// TODO Auto-generated method stub
return null;
return data.conj(value);
}

@Override
public ASequence<ACell> slice(long start, long end) {
// TODO Auto-generated method stub
return null;
return data.slice(start,end);
}

@Override
public AList<ACell> cons(ACell x) {
// TODO Auto-generated method stub
return null;
return data.cons(x);
}

@Override
public AVector<ACell> subVector(long start, long length) {
// TODO Auto-generated method stub
return null;
return data.subVector(start, length);
}

@Override
protected ListIterator<ACell> listIterator(long l) {
// TODO Auto-generated method stub
return null;
return data.listIterator(l);
}

@Override
public ASequence<ACell> reverse() {
// TODO Auto-generated method stub
return null;
return data.reverse();
}

@Override
public AType getType() {
// TODO Auto-generated method stub
return null;
return Types.CAD3;
}

@Override
public AVector<ACell> toVector() {
// TODO Auto-generated method stub
return null;
return data;
}

@Override
protected <R> void copyToArray(R[] arr, int offset) {
// TODO Auto-generated method stub

data.copyToArray(arr, offset);
}

@Override
public int getRefCount() {
return data.getRefCount();
}

@Override
public Ref<ACell> getRef(int i) {
return data.getRef(i);
}

@Override
public ACell updateRefs(IRefFunction func) {
AVector<ACell> newData=data.updateRefs(func);
if (newData==data) return this;
DenseRecord dr= new DenseRecord(tag,newData);
dr.attachEncoding(getEncoding());
return dr;
}


}
6 changes: 5 additions & 1 deletion convex-core/src/main/java/convex/core/data/Format.java
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,11 @@ private static <T extends ACell> T readTransaction(byte tag, Blob b, int pos) th
} else if (tag == Tag.MULTI) {
return (T) Multi.read(b,pos);
}
throw new BadFormatException(badTagMessage(tag));

// Might be a generic Dense Record
DenseRecord dr=DenseRecord.read(tag,b,pos);
if (dr==null) throw new BadFormatException(badTagMessage(tag));
return (T) dr;
}

/**
Expand Down
3 changes: 1 addition & 2 deletions convex-core/src/main/java/convex/core/data/MapEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
* implementation class for handling entries in Convex maps, and also to support the Java Map.Entry
* interface for compatibility and developer convenience.
*
* From a CVM perspective, a MapEntry is just a regular 2 element Vector. As such, MapEntry is *not* canonical
* and getting the canonical form of a MapEntry requires converting to a Vector
* From a CVM perspective, a MapEntry is just a regular 2 element Vector.
*
* Contains exactly 2 elements, one for key and one for value
*
Expand Down
14 changes: 14 additions & 0 deletions convex-core/src/main/java/convex/core/data/Tag.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class Tag {

// ==========================================
// Sparsely coded record (0xAx)
public static final byte SPARSE_RECORD_BASE = (byte) 0xA0;

public static final byte STATE = (byte) 0xA0;
public static final byte ACCOUNT_STATUS = (byte) 0xA1;
public static final byte PEER_STATUS = (byte) 0xA2;
Expand Down Expand Up @@ -98,6 +100,8 @@ public class Tag {

// ==========================================
// Densely coded record (0xDx)
public static final byte DENSE_RECORD_BASE = (byte) 0xD0;

public static final byte INVOKE = (byte) 0xD0;
public static final byte TRANSFER = (byte) 0xD1;
public static final byte CALL = (byte) 0xD2;
Expand All @@ -121,6 +125,16 @@ public class Tag {
// Illegal / reserved for special values (0xFx)
public static final byte ILLEGAL = (byte) 0xFF;


/**
* Get the general category for a given Tag (high hex digit)
* @param tag Tag Byte
* @return Category e.g. 0xC0 for coded data
*/
public static byte category(int tag) {
return (byte) (tag&0xF0);
}



}
Loading

0 comments on commit 1ef0fef

Please sign in to comment.