content: /*
   * Copyright (C) 1999-2019 Alibaba Group Holding Limited
   */
  package com.alibaba.innodb.java.reader.page.fsphdr;
  
  import com.alibaba.innodb.java.reader.ListBaseNode;
  import com.alibaba.innodb.java.reader.util.SliceInput;
  
  import lombok.Data;
  
  /**
   * InnoDB allocates FSP_HDR and XDES pages at fixed locations within the space.
   *
   * @author xu.zx
   */
  @Data
  public class FspHeader {
  
    /** 该文件对应的space id. */
    private long space;
  
    /**
     * Highest page number in file (size).
     * <p>
     * 当前表空间总的PAGE个数，扩展文件时需要更新该值fsp_try_extend_data_file_with_pages.
     */
    private long size;
  
    /**
     * Highest page number initialized (free limit).
     * <p>
     * 当前尚未初始化的最小Page No。从该Page往后的都尚未加入到表空间的FREE LIST上。
     */
    private long freeLimit;
  
    /**
     * 当前表空间的FLAG信息.
     * <pre>
     * Macro Desc
     * FSP_FLAGS_POS_ZIP_SSIZE 压缩页的block size，如果为0表示非压缩表
     * FSP_FLAGS_POS_ATOMIC_BLOBS 使用的是compressed或者dynamic的行格式
     * FSP_FLAGS_POS_PAGE_SSIZE InnerPage Size
     * FSP_FLAGS_POS_DATA_DIR 如果该表空间显式指定了data_dir，则设置该flag
     * FSP_FLAGS_POS_SHARED 是否是共享的表空间，如5.7引入的General Tablespace，可以在一个表空间中创建多个表
     * FSP_FLAGS_POS_TEMPORARY 是否是临时表空间
     * FSP_FLAGS_POS_ENCRYPTION 是否是加密的表空间，MySQL 5.7.11引入
     * FSP_FLAGS_POS_UNUSED 未使用的位
     * </pre>
     */
    private long flags;
  
    /** FSP_FREE_FRAG链表上已被使用的Page数，用于快速计算该链表上可用空闲Page数. */
    private long numberOfPagesUsed;
  
    /** 当一个Extent中所有page都未被使用时，放到该链表上，可以用于随后的分配. */
    private ListBaseNode free;
  
    /**
     * FREE_FRAG链表的Base Node，通常这样的Extent中的Page可能归属于不同的segment，
     * 用于segment frag array page的分配.
     */
    private ListBaseNode freeFrag;
  
    /** Extent中所有的page都被使用掉时，会放到该链表上，当有Page从该Extent释放时，则移回FREE_FRAG链表. */
    private ListBaseNode fullFrag;
  
    /** 当前文件中最大Segment ID + 1，用于段分配时的seg id计数器. */
    private long nextUsedSegmentId;
  
    /** 已被完全用满的Inode Page链表. */
    private ListBaseNode fullInodes;
  
    /** 至少存在一个空闲Inode Entry的Inode Page被放到该链表上. */
    private ListBaseNode freeInodes;
  
    public static FspHeader fromSlice(SliceInput input) {
      FspHeader fspHeader = new FspHeader();
      fspHeader.setSpace(input.readUnsignedInt());
      // FSP_NOT_USED 4 bytes reversed
      input.skipBytes(4);
      fspHeader.setSize(input.readUnsignedInt());
      fspHeader.setFreeLimit(input.readUnsignedInt());
      fspHeader.setFlags(input.readUnsignedInt());
      fspHeader.setNumberOfPagesUsed(input.readUnsignedInt());
      fspHeader.setFree(ListBaseNode.fromSlice(input));
      fspHeader.setFreeFrag(ListBaseNode.fromSlice(input));
      fspHeader.setFullFrag(ListBaseNode.fromSlice(input));
      fspHeader.setNextUsedSegmentId(input.readLong());
      fspHeader.setFullInodes(ListBaseNode.fromSlice(input));
      fspHeader.setFreeInodes(ListBaseNode.fromSlice(input));
      return fspHeader;
    }
  
  }
  