// Path: src/org/jgroups/raft/filelog/FilePositionCache.java
// public static final int NO_CAPACITY = -2;
// 
// Path: src/org/jgroups/raft/filelog/FilePositionCache.java
// public static final int OK = 1;
// 
// Path: src/org/jgroups/raft/filelog/FilePositionCache.java
// public static final int TOO_OLD = -1;
// 
// Path: src/org/jgroups/protocols/raft/LogEntry.java
// public class LogEntry implements Streamable {
//     protected int     term;     // the term of this entry
//     protected byte[]  command;  // the command (interpreted by the state machine)
//     protected int     offset;   // may get removed (always 0)
//     protected int     length;   // may get removed (always command.length)
//     protected boolean internal; // if true, the contents of the buffer are an InternalCommand
// 
// 
//     public LogEntry() {}
// 
//     public LogEntry(int term, byte[] command) {
//         this(term, command, 0, command != null? command.length : 0);
//     }
// 
//     public LogEntry(int term, byte[] command, int offset, int length) {
//         this(term, command, offset, length, false);
//     }
// 
// 
//     public LogEntry(int term,byte[] command,int offset,int length, boolean internal) {
//         this.term=term;
//         this.command=command;
//         this.offset=offset;
//         this.length=length;
//         this.internal=internal;
//     }
// 
//     public int     term()     {return term;}
//     public byte[]  command()  {return command;}
//     public int     offset()   {return offset;}
//     public int     length()   {return length;}
//     public boolean internal() {return internal;}
// 
//     public void writeTo(DataOutput out) throws IOException {
//         Bits.writeIntCompressed(term, out);
//         Util.writeByteBuffer(command, offset, length, out);
//         out.writeBoolean(internal);
//     }
// 
//     public void readFrom(DataInput in) throws IOException {
//         term=Bits.readIntCompressed(in);
//         command=Util.readByteBuffer(in);
//         offset=0;
//         length=command != null? command.length : 0;
//         internal=in.readBoolean();
//     }
// 
//     public String toString() {
//         StringBuilder str = new StringBuilder();
//         str.append("term=").append(term).append(" (").append(command != null? command.length : 0).append(" bytes)");
//         if(internal) str.append(" [internal]");
//         return str.toString();
//     }
// 
// 
// }


import static org.jgroups.raft.filelog.FilePositionCache.NO_CAPACITY;
import static org.jgroups.raft.filelog.FilePositionCache.OK;
import static org.jgroups.raft.filelog.FilePositionCache.TOO_OLD;
import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Objects;
import java.util.concurrent.locks.StampedLock;
import java.util.function.ObjIntConsumer;
import org.jgroups.Global;
import org.jgroups.logging.Log;
import org.jgroups.logging.LogFactory;
import org.jgroups.protocols.raft.LogEntry;
      final byte magic;
      final int totalLength;
      final int term;
      final int index;
      final int dataLength;

      Header(long position, int index, LogEntry entry) {
         Objects.requireNonNull(entry);
         this.position = position;
         this.magic = MAGIC_NUMBER;
         this.index = index;
         this.term = entry.term();
         this.dataLength = entry.length();
         this.totalLength = HEADER_SIZE + dataLength;
      }

      Header(long position, ByteBuffer buffer) {
         this.position = position;
         this.magic = buffer.get();
         this.totalLength = buffer.getInt();
         this.term = buffer.getInt();
         this.index = buffer.getInt();
         this.dataLength = buffer.getInt();
      }

      public void writeTo(ByteBuffer buffer) {
         buffer.put(magic);
         buffer.putInt(totalLength);
         buffer.putInt(term);
         buffer.putInt(index);
// Path: src/org/jgroups/raft/filelog/FilePositionCache.java
// public static final int NO_CAPACITY = -2;
// 
// Path: src/org/jgroups/raft/filelog/FilePositionCache.java
// public static final int OK = 1;
// 
// Path: src/org/jgroups/raft/filelog/FilePositionCache.java
// public static final int TOO_OLD = -1;
// 
// Path: src/org/jgroups/protocols/raft/LogEntry.java
// public class LogEntry implements Streamable {
//     protected int     term;     // the term of this entry
//     protected byte[]  command;  // the command (interpreted by the state machine)
//     protected int     offset;   // may get removed (always 0)
//     protected int     length;   // may get removed (always command.length)
//     protected boolean internal; // if true, the contents of the buffer are an InternalCommand
// 
// 
//     public LogEntry() {}
// 
//     public LogEntry(int term, byte[] command) {
//         this(term, command, 0, command != null? command.length : 0);
//     }
// 
//     public LogEntry(int term, byte[] command, int offset, int length) {
//         this(term, command, offset, length, false);
//     }
// 
// 
//     public LogEntry(int term,byte[] command,int offset,int length, boolean internal) {
//         this.term=term;
//         this.command=command;
//         this.offset=offset;
//         this.length=length;
//         this.internal=internal;
//     }
// 
//     public int     term()     {return term;}
//     public byte[]  command()  {return command;}
//     public int     offset()   {return offset;}
//     public int     length()   {return length;}
//     public boolean internal() {return internal;}
// 
//     public void writeTo(DataOutput out) throws IOException {
//         Bits.writeIntCompressed(term, out);
//         Util.writeByteBuffer(command, offset, length, out);
//         out.writeBoolean(internal);
//     }
// 
//     public void readFrom(DataInput in) throws IOException {
//         term=Bits.readIntCompressed(in);
//         command=Util.readByteBuffer(in);
//         offset=0;
//         length=command != null? command.length : 0;
//         internal=in.readBoolean();
//     }
// 
//     public String toString() {
//         StringBuilder str = new StringBuilder();
//         str.append("term=").append(term).append(" (").append(command != null? command.length : 0).append(" bytes)");
//         if(internal) str.append(" [internal]");
//         return str.toString();
//     }
// 
// 
// }


// Path: src/org/jgroups/raft/filelog/LogEntryStorage.java
import static org.jgroups.raft.filelog.FilePositionCache.NO_CAPACITY;
import static org.jgroups.raft.filelog.FilePositionCache.OK;
import static org.jgroups.raft.filelog.FilePositionCache.TOO_OLD;
import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Objects;
import java.util.concurrent.locks.StampedLock;
import java.util.function.ObjIntConsumer;
import org.jgroups.Global;
import org.jgroups.logging.Log;
import org.jgroups.logging.LogFactory;
import org.jgroups.protocols.raft.LogEntry;

      final byte magic;
      final int totalLength;
      final int term;
      final int index;
      final int dataLength;

      Header(long position, int index, LogEntry entry) {
         Objects.requireNonNull(entry);
         this.position = position;
         this.magic = MAGIC_NUMBER;
         this.index = index;
         this.term = entry.term();
         this.dataLength = entry.length();
         this.totalLength = HEADER_SIZE + dataLength;
      }

      Header(long position, ByteBuffer buffer) {
         this.position = position;
         this.magic = buffer.get();
         this.totalLength = buffer.getInt();
         this.term = buffer.getInt();
         this.index = buffer.getInt();
         this.dataLength = buffer.getInt();
      }

      public void writeTo(ByteBuffer buffer) {
         buffer.put(magic);
         buffer.putInt(totalLength);
         buffer.putInt(term);
         buffer.putInt(index);
         buffer.putInt(dataLength);