Class RefCountedCow<T>

java.lang.Object
io.deephaven.engine.rowset.impl.RefCountedCow<T>
Type Parameters:
T - A class that will extend us, to get RefCounted functionality.
Direct Known Subclasses:
RspArray, SortedRanges

public abstract class RefCountedCow<T> extends Object

This class enables a pattern of use where objects can be shared from multiple references/identities while they are used read-only. Note this is not thread safe. A class derives from this class and users of it call getWriteRef() to obtain a reference that can be modified. That may return the same object (with an increased ref count), or may return a deep copy of it if other readers of the object exist. Effectively this creates a copy-on-write sharing strategy.

Example:

 

   class MyType extends RefCountedCow<MyType> {
       &#64;Override protected MyType self() { return this; }
       &#64;Override protected MyType copy() { ... } // return a deep copy of this object

       ...
   }

   public class UsesMyType {
       private MyType m;

       public void acquire() { m.acquire(); }
       public void release() { m.release(); }

       private void writeCheck() { m = m.getWriteRef(); }

       public void someWriteOperation() {
           writeCheck();
           // regular implementation calling mutation operations on m.
       }

       public void someReadOnlyOperation() {
           // No need to call writeCheck here.
       }

       ...
 }

 
 

Uses the "Curiously Recurring Generic Pattern"

Note this implementation does minimal concurrency protection, since it assumes it will run under the protection mechanisms of live update table and its clock, ie, reads can concurrently access objects being mutated, but will realize near the end their operation was invalidated by a clock change and will toss their results.

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    final void
    Increase our reference count.
    protected boolean
    Query whether this object will copy itself first before mutations.
    final T
    Obtain a new reference to this object; the reference count will increase.
    abstract T
    Get a deep copy of the current object, not shared with anybody.
    Obtain a reference to this object that can be modified without affecting other references.
    protected void
    Derived classes that want to get notified after release can override this method.
    protected void
    Derived classes that want to get notified before acquire can override this method.
    final int
     
    final int
    Decrease our reference count.
    protected abstract T
    Derived classes should implement self() by simply "return this" of the right type.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • RefCountedCow

      public RefCountedCow()
  • Method Details

    • acquire

      public final void acquire()
      Increase our reference count.
    • cowRef

      public final T cowRef()
      Obtain a new reference to this object; the reference count will increase. This operation is cheap and does not do a deep copy of the object's payload; if a mutator is called through this reference, the reference will make a copy of its payload first, before applying the mutation, to keep other read only accessor of the previously shared payload unnaffected. Note this assumes a pattern of use for derived classes where mutators return a reference, which may or may not point to the same object on which the mutation was called. Also note this is not thread safe.
      Returns:
      A reference that will copy-on-write on its payload if it is mutated.
    • release

      public final int release()
      Decrease our reference count.
      Returns:
      the resulting reference count value.
    • refCount

      @VisibleForTesting public final int refCount()
    • deepCopy

      public abstract T deepCopy()
      Get a deep copy of the current object, not shared with anybody. Note this is not thread safe.
      Returns:
      A full, deep copy of this object with a reference count of 1 (not shared).
    • self

      protected abstract T self()
      Derived classes should implement self() by simply "return this" of the right type. This method exists only as an implementation artifact for a type safe implementation of the curiously recurring generic pattern.
      Returns:
      this object, with the right, most derived type.
    • notifyBeforeAcquire

      protected void notifyBeforeAcquire()
      Derived classes that want to get notified before acquire can override this method.
    • notifyAfterRelease

      protected void notifyAfterRelease()
      Derived classes that want to get notified after release can override this method.
    • getWriteRef

      public T getWriteRef()
      Obtain a reference to this object that can be modified without affecting other references. Note this is not thread safe.
      Returns:
      If this object is shared, a deep copy of this object, otherwise the object itself.
    • canWrite

      protected boolean canWrite()
      Query whether this object will copy itself first before mutations. Note this is not thread safe.
      Returns:
      true if this object is not shared and can be mutated directly