Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.infinispan.commons.marshall;
  
  import java.util.List;
  
An advanced externalizer that when implemented will allow for child instances that also extend this class to use object instances instead of serializing a brand new object.

Author(s):
wburns
Since:
7.1
 
 public abstract class InstanceReusingAdvancedExternalizer<T> extends AbstractExternalizer<T> {
    static class ReusableData {
       IdentityIntMap<Objectmap = new IdentityIntMap<>();
       int offset;
    }
    private static ThreadLocal<ReusableDatacachedWriteObjects = new ThreadLocal<ReusableData>();
    private static ThreadLocal<List<Object>> cachedReadObjects = new ThreadLocal<List<Object>>();
    
    private static final int ID_NO_REPEAT                 = 0x01;
    private static final int ID_REPEAT_OBJECT_NEAR        = 0x02;
    private static final int ID_REPEAT_OBJECT_NEARISH     = 0x03;
    private static final int ID_REPEAT_OBJECT_FAR         = 0x04;
    
       this(true);
    }
    
    public InstanceReusingAdvancedExternalizer(boolean hasChildren) {
       this. = hasChildren;
    }
   
   
This boolean controls whether or not it makes sense to actually create the context or not. In the case of classes that don't expect to have children that support this they shouldn't do the creation
 
    private final boolean hasChildren;
    
    @Override
    public final void writeObject(ObjectOutput output, T objectthrows IOException {
       ReusableData data = .get();
       boolean shouldRemove;
       if ( && data == null) {
          data = new ReusableData();
          .set(data);
          shouldRemove = true;
       } else {
          shouldRemove = false;
       }
       try {
          int id;
          if (data != null && (id = data.map.get(object, -1)) != -1) {
             final int diff = id - data.offset;
             if (diff >= -256) {
                 output.write();
                 output.write(diff);
             } else if (diff >= -65536) {
                 output.write();
                 output.writeShort(diff);
             } else {
                 output.write();
                 output.writeInt(id);
             }
          } else {
             output.write();
             doWriteObject(outputobject);
             // Set this before writing object in case of circular dependencies
             if (data != null) {
                data.map.put(objectdata.offset++);
             }
          }
       } finally {
          if (shouldRemove) {
             .remove();
          }
       }
    }
    
    public abstract void doWriteObject(ObjectOutput output, T objectthrows IOException;
    
    @Override
    public final T readObject(ObjectInput inputthrows IOExceptionClassNotFoundException {
       List<Objectdata = .get();
       boolean shouldRemove;
       if ( && data == null) {
          data = new ArrayList<>();
          .set(data);
          shouldRemove = true;
       } else {
          shouldRemove = false;
       }
       try {
          int type = input.read();
         switch (type) {
         case :
            T object = doReadObject(input);
            if (data != null) {
               data.add(object);
            }
            return object;
         case :
            int offset = input.read() | 0xffffff00;
            return getFromCache(dataoffset + data.size());
         case :
            offset = input.readShort() | 0xffff0000;
            return getFromCache(dataoffset + data.size());
         case :
            return getFromCache(datainput.readInt());
         default:
            throw new IllegalStateException("Unexpected byte encountered" + type);
         }
      } finally {
         if (shouldRemove) {
            .remove();
         }
      }
   }
   
   private T getFromCache(List<Objectdataint indexthrows InvalidObjectException {
      try {
         Object obj = data.get(index);
         if (obj != null) {
            return (T) obj;
         }
     } catch (IndexOutOfBoundsException e) {
     }
     throw new InvalidObjectException("Attempt to read a backreference for " + getClass() + " with an invalid ID (absolute " 
           + index + ")");
   }
   
   public abstract T doReadObject(ObjectInput inputthrows IOExceptionClassNotFoundException;
New to GrepCode? Check out our FAQ X