Class ACell

All Implemented Interfaces:
IValidated, IWriteable
Direct Known Subclasses:
ACountable, AFn, AOp, APrimitive, ASymbolic, Syntax

public abstract class ACell extends AObject implements IWriteable, IValidated
Abstract base class for Cells. Cells may contain Refs to other Cells, which can be tested with getRefCount() All data objects intended for on-chain usage / serialisation should extend this. "It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures." - Alan Perlis
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected Ref<ACell>
    Cached Ref.
    static final ACell[]
    An empty Java array of cells

    Fields inherited from class convex.core.data.AObject

    encoding
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    <T extends ACell>
    T
     
    <T extends ACell>
    T
    announce(Consumer<Ref<ACell>> noveltyHandler)
     
    void
    attachMemorySize(long memorySize)
    Updates the memorySize of this Cell Not valid for embedded Cells, may throw IllegalOperationException()
    void
    attachRef(Ref<?> ref)
    Updates the cached ref of this Cell
    Gets the cached blob representing this Cell's Encoding in binary format, if it exists.
    protected final Hash
    Gets the Hash if already computed, or null if not yet available
    protected long
    Calculates the Memory Size for this Cell.
    static <T extends ACell>
    T
    createAnnounced(T value, Consumer<Ref<ACell>> noveltyHandler)
    Creates an ANNOUNCED Ref with the given value in the current store.
    protected final Blob
    Creates the encoding for this cell.
    static <T extends ACell>
    Ref<T>
    createPersisted(T value)
    Creates a persisted Ref with the given value in the current store.
    static <T extends ACell>
    Ref<T>
    createPersisted(T value, Consumer<Ref<ACell>> noveltyHandler)
    Creates a persisted Ref with the given value in the current store.
    protected <R extends ACell>
    Ref<R>
    Creates a new Ref for this Cell
    abstract int
    encode(byte[] bs, int pos)
    Writes this Cell's encoding to a byte array, including a tag byte which will be written first.
    protected abstract int
    encodeRaw(byte[] bs, int pos)
    Writes this Cell's encoding to a byte array, excluding the tag byte.
    boolean
    Checks for equality with another Cell.
    final boolean
     
    final ACell
    Gets the canonical representation of this Cell.
    <R extends ACell>
    Ref<R>[]
    Gets an array of child Refs for this Cell, in the same order as order accessible by getRef.
    final Blob
    Gets the canonical encoded byte representation of this cell.
    int
    Method to calculate the encoding length of a Cell.
    final Hash
    Hash of data Encoding of this cell, equivalent to the Value ID.
    final long
    Gets the Memory Size of this Cell, computing it if required.
    final <R extends ACell>
    Ref<R>
    Gets the Ref for this Cell, creating a new direct reference if necessary
    <R extends ACell>
    Ref<R>
    getRef(int i)
    Gets a numbered child Ref from within this Cell.
    abstract int
    Gets the number of Refs contained within this Cell.
    abstract byte
    Gets the tag byte for this cell.
    Gets the most specific known runtime Type for this Cell.
    int
    Gets the Java hashCode for this cell.
    abstract boolean
    Returns true if this Cell is in a canonical representation for message writing.
    boolean
    Tests if this Cell is completely encoded, i.e.
    abstract boolean
    Returns true if this Cell represents a first class CVM Value.
    boolean
    Determines if this Cell Represents an embedded object.
    <T extends ACell>
    T
     
    <T extends ACell>
    T
    mark(Consumer<Ref<ACell>> noveltyHandler)
     
    abstract ACell
    Converts this Cell to its canonical version.
    toCVMString(long limit)
    Returns the CVM String representation of this Cell.
    Returns the Java String representation of this Cell.
    Updates all Refs in this object using the given function.
    void
    Validates the complete structure of this object.
    abstract void
    Validates the local structure and invariants of this cell.

    Methods inherited from class convex.core.data.AObject

    attachEncoding, print, print, print

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait

    Methods inherited from interface convex.core.data.IWriteable

    estimatedEncodingSize
  • Field Details

    • EMPTY_ARRAY

      public static final ACell[] EMPTY_ARRAY
      An empty Java array of cells
    • cachedRef

      protected Ref<ACell> cachedRef
      Cached Ref. This is useful to manage persistence. Also cached Ref MUST refer to canonical value
  • Constructor Details

    • ACell

      public ACell()
  • Method Details

    • validate

      public void validate() throws InvalidDataException
      Description copied from interface: IValidated
      Validates the complete structure of this object. It is necessary to ensure all child Refs are validated, so the general contract for validate is:
      1. Call super.validate() - which will indirectly call validateCell()
      2. Call validate() on any contained cells in this class
      Specified by:
      validate in interface IValidated
      Throws:
      InvalidDataException - If the data Value is invalid in any way
    • validateCell

      public abstract void validateCell() throws InvalidDataException
      Validates the local structure and invariants of this cell. Called by validate() super implementation. Should validate directly contained data, but should not validate all other structure of this cell. In particular, should not traverse potentially missing child Refs.
      Throws:
      InvalidDataException - If the Cell is invalid
    • getHash

      public final Hash getHash()
      Hash of data Encoding of this cell, equivalent to the Value ID. Calling this method may force hash computation if needed.
      Returns:
      The Hash of this cell's encoding.
    • getTag

      public abstract byte getTag()
      Gets the tag byte for this cell. The tag byte is always equal to the first byte of the Cell's canonical Encoding, and is sufficient to distinguish how to read the rest of the encoding.
      Returns:
      Tag byte for this Cell
    • cachedHash

      protected final Hash cachedHash()
      Gets the Hash if already computed, or null if not yet available
      Returns:
      Cached Hash value, or null if not available
    • hashCode

      public int hashCode()
      Gets the Java hashCode for this cell. Must be consistent with equals. Default is the first bytes (big-endian) of the Cell Encoding's hash, since this is consistent with encoding-based equality. However, different Types may provide more efficient hashcodes provided that the usual invariants are preserved
      Overrides:
      hashCode in class Object
      Returns:
      integer hash code.
    • equals

      public final boolean equals(Object a)
      Overrides:
      equals in class Object
    • getEncoding

      public final Blob getEncoding()
      Gets the canonical encoded byte representation of this cell.
      Overrides:
      getEncoding in class AObject
      Returns:
      A Blob representing this cell in encoded form
    • getCanonical

      public final ACell getCanonical()
      Gets the canonical representation of this Cell. O(1) if canonical representation is already generated, may be O(n) otherwise.
      Returns:
      A Blob representing this cell in encoded form
    • equals

      public boolean equals(ACell a)
      Checks for equality with another Cell. In general, Cells are considered equal if they have the same canonical representation, i.e. an identical encoding with the same hash value. Subclasses SHOULD override this if they have a more efficient equals implementation. MUST NOT require reads from Store.
      Parameters:
      a - Cell to compare with. May be null.
      Returns:
      True if this cell is equal to the other object
    • encode

      public abstract int encode(byte[] bs, int pos)
      Writes this Cell's encoding to a byte array, including a tag byte which will be written first. Cell must be canonical, or else an error may occur.
      Specified by:
      encode in interface IWriteable
      Parameters:
      bs - A byte array to which to write the encoding
      pos - The offset into the byte array
      Returns:
      New position after writing
    • encodeRaw

      protected abstract int encodeRaw(byte[] bs, int pos)
      Writes this Cell's encoding to a byte array, excluding the tag byte.
      Parameters:
      bs - A byte array to which to write the encoding
      pos - The offset into the byte array
      Returns:
      New position after writing
    • createEncoding

      protected final Blob createEncoding()
      Creates the encoding for this cell. Cell must be canonical, or else an error may occur. The encoding itself is a raw Blob, which may be non-canonical.
      Specified by:
      createEncoding in class AObject
      Returns:
      Blob Encoding of Object
    • toString

      public String toString()
      Returns the Java String representation of this Cell. The String representation is intended to be a easy-to-read textual representation of the Cell's data content.
      Overrides:
      toString in class Object
    • toCVMString

      public AString toCVMString(long limit)
      Returns the CVM String representation of this Cell. Normally, this is as printed, but may be different for some types. MUST return null in O(1) time if the length of the CVM String would exceed limit. The String representation is intended to be a easy-to-read textual representation of the Cell's data content.
      Parameters:
      limit - Limit of CVM String length in UTF-8 bytes
      Returns:
      CVM String, or null if limit exceeded
    • cachedEncoding

      public Blob cachedEncoding()
      Gets the cached blob representing this Cell's Encoding in binary format, if it exists.
      Returns:
      The cached blob for this cell, or null if not available.
    • calcMemorySize

      protected long calcMemorySize()
      Calculates the Memory Size for this Cell. Requires any child Refs to be either Direct or of persisted status at minimum, or you might get a MissingDataException
      Returns:
      Memory Size of this Cell
    • getEncodingLength

      public int getEncodingLength()
      Method to calculate the encoding length of a Cell. May be overridden to avoid creating encodings during memory size calculations. This reduces hashing!
      Returns:
      Exact encoding length of this Cell
    • getMemorySize

      public final long getMemorySize()
      Gets the Memory Size of this Cell, computing it if required. The memory size is the total storage requirement for this cell. Embedded cells do not require storage for their own encoding, but may require storage for nested non-embedded Refs.
      Returns:
      Memory Size of this Cell
    • isEmbedded

      public boolean isEmbedded()
      Determines if this Cell Represents an embedded object. Embedded objects are encoded directly into the encoding of the containing Cell (avoiding the need for a hashed reference). Subclasses should override this if they have a cheap O(1) way to determine if they are embedded or otherwise.
      Returns:
      true if Cell is embedded, false otherwise
    • isCanonical

      public abstract boolean isCanonical()
      Returns true if this Cell is in a canonical representation for message writing. Non-canonical objects may be used on a temporary internal basis, they must always be converted to canonical representations for external use (e.g. Encoding).
      Returns:
      true if the object is in canonical format, false otherwise
    • toCanonical

      public abstract ACell toCanonical()
      Converts this Cell to its canonical version. Must return this Cell if already canonical, may be O(n) in size of value otherwise.
      Returns:
      Canonical version of Cell
    • isCVMValue

      public abstract boolean isCVMValue()
      Returns true if this Cell represents a first class CVM Value. Sub-structural cells that are not themselves first class values should return false, pretty much everything else should return true. Note: CVM values might not be in a canonical format, e.g. temporary data structures
      Returns:
      true if the object is a CVM Value, false otherwise
    • getRefCount

      public abstract int getRefCount()
      Gets the number of Refs contained within this Cell. This number is final / immutable for any given instance and is defined by the Cell encoding rules. WARNING: may not be valid id Cell is not canonical Contained Refs may be either external or embedded.
      Returns:
      The number of Refs in this Cell
    • getRef

      public final <R extends ACell> Ref<R> getRef()
      Gets the Ref for this Cell, creating a new direct reference if necessary
      Type Parameters:
      R - Type of Cell
      Returns:
      Ref for this Cell
    • createRef

      protected <R extends ACell> Ref<R> createRef()
      Creates a new Ref for this Cell
      Type Parameters:
      R - Type of Cell
      Returns:
      New Ref instance
    • getRef

      public <R extends ACell> Ref<R> getRef(int i)
      Gets a numbered child Ref from within this Cell. WARNING: May be unreliable is cell is not canonical
      Type Parameters:
      R - Type of referenced Cell
      Parameters:
      i - Index of ref to get
      Returns:
      The Ref at the specified index
    • updateRefs

      public ACell updateRefs(IRefFunction func)
      Updates all Refs in this object using the given function. The function *must not* change the hash value of Refs, in order to ensure structural integrity of modified data structures. The implementation *should* re-attach any original encoding in order to prevent re-encoding or surplus hashing This is a building block for a very sneaky trick that enables use to do a lot of efficient operations on large trees of smart references. Must return the same object if no Refs are altered.
      Parameters:
      func - Ref update function
      Returns:
      Cell with updated Refs
    • getChildRefs

      public <R extends ACell> Ref<R>[] getChildRefs()
      Gets an array of child Refs for this Cell, in the same order as order accessible by getRef. Concrete implementations may override this to optimise performance.
      Type Parameters:
      R - Type of referenced Cell
      Returns:
      Array of Refs
    • getType

      public AType getType()
      Gets the most specific known runtime Type for this Cell.
      Returns:
      The Type of this Call
    • attachMemorySize

      public void attachMemorySize(long memorySize)
      Updates the memorySize of this Cell Not valid for embedded Cells, may throw IllegalOperationException()
      Parameters:
      memorySize - Memory size to assign
    • attachRef

      public void attachRef(Ref<?> ref)
      Updates the cached ref of this Cell
      Parameters:
      ref - Ref to assign
    • createAnnounced

      public static <T extends ACell> T createAnnounced(T value, Consumer<Ref<ACell>> noveltyHandler)
      Creates an ANNOUNCED Ref with the given value in the current store. Novelty handler is called for all new Refs that are persisted (recursively), starting from lowest levels.
      Type Parameters:
      T - Type of Value
      Parameters:
      value - Value to announce
      noveltyHandler - Novelty handler to call for any Novelty (may be null)
      Returns:
      Persisted Ref
    • announce

      public <T extends ACell> T announce()
    • announce

      public <T extends ACell> T announce(Consumer<Ref<ACell>> noveltyHandler)
    • mark

      public <T extends ACell> T mark()
    • mark

      public <T extends ACell> T mark(Consumer<Ref<ACell>> noveltyHandler)
    • createPersisted

      public static <T extends ACell> Ref<T> createPersisted(T value, Consumer<Ref<ACell>> noveltyHandler)
      Creates a persisted Ref with the given value in the current store. Novelty handler is called for all new Refs that are persisted (recursively), starting from lowest levels (depth first order)
      Type Parameters:
      T - Type of Value
      Parameters:
      value - Any CVM value to persist
      noveltyHandler - Novelty handler to call for any Novelty (may be null)
      Returns:
      Persisted Ref
    • createPersisted

      public static <T extends ACell> Ref<T> createPersisted(T value)
      Creates a persisted Ref with the given value in the current store. Returns the current Ref if already persisted
      Type Parameters:
      T - Type of Value
      Parameters:
      value - Any CVM value to persist
      Returns:
      Ref to the given value
    • isCompletelyEncoded

      public boolean isCompletelyEncoded()
      Tests if this Cell is completely encoded, i.e. has no external Refs. This implies that the complete Cell can be represented in a single encoding.
      Returns:
      true if completely encoded, false otherwise