Class DBPage

  • All Implemented Interfaces:
    Pinnable, java.lang.AutoCloseable

    public class DBPage
    extends java.lang.Object
    implements Pinnable, java.lang.AutoCloseable
    This class represents a single page in a database file. The page's (zero-based) index in the file, and whether the page has been changed in memory, are tracked by the object.

    Database pages do not provide any locking mechanisms to guard against concurrent access. Locking must be managed at a level above what this class provides.

    The class provides methods to read and write a wide range of data types. Multibyte values are stored in big-endian format, with the most significant byte (MSB) stored at the lowest index, and the least significant byte (LSB) stored at the highest index. (This is also the network byte order specified by the Internet Protocol.)

    See Also:
    PageReader, PageWriter
    Design Note:
    (Donnie) It is very important that the page is marked dirty before any changes are made, because this is the point when the old version of the page data is copied before changes are made. Additionally, the page's data must not be manipulated separately from the methods provided by this class, or else the old version of the page won't be recorded properly.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private BufferManager bufferManager
      The buffer manager is used by this class to request buffer space when needed, so that a maximum cap can be placed on memory usage.
      private DBFile dbFile
      A reference to the database file that this page is from.
      private boolean dirty
      This flag is true if this page has been modified in memory.
      private static org.apache.logging.log4j.Logger logger
      A logging object for reporting anything interesting that happens.
      private byte[] oldPageData
      When the page is marked dirty, this gets set to the original version of the page, so that we can properly record changes to the write-ahead log.
      private byte[] pageData
      The actual data for the table-page.
      private LogSequenceNumber pageLSN
      For dirty pages, this field is set to the Log Sequence Number of the write-ahead log record corresponding to the most recent write to the page.
      private int pageNo
      The page number in the table file.
      private java.util.concurrent.atomic.AtomicInteger pinCount
      The pin-count of this page.
    • Constructor Summary

      Constructors 
      Constructor Description
      DBPage​(BufferManager bufferManager, DBFile dbFile, int pageNo)
      Constructs a new, empty table-page for the specified table file.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void close()  
      java.lang.String getChangesAsString()
      This helper method returns a formatted string describing all changes made to the page's contents; that is, the differences between the pageData and the oldPageData byte-arrays.
      DBFile getDBFile()
      Returns the database file that this page is contained within.
      byte[] getOldPageData()
      Returns the byte-array of the page's data at the last point when the page became dirty, or null if the page is currently clean.
      byte[] getPageData()
      Returns the byte-array of the page's data.
      LogSequenceNumber getPageLSN()  
      int getPageNo()
      Returns the page-number of this database page.
      int getPageSize()
      Returns the page size in bytes.
      int getPinCount()
      Returns the total number of times the object has been pinned.
      void invalidate()
      This method makes the DBPage invalid by clearing all of its internal references.
      boolean isDirty()
      Returns true if the page's data has been changed in memory; false otherwise.
      boolean isFromDBFile​(DBFile databaseFile)
      Returns true if this page is from the specified database file.
      boolean isPinned()
      Returns true if the object is currently pinned, false otherwise.
      void moveDataRange​(int srcPosition, int dstPosition, int length)
      Move the specified data region in the page.
      void pin()
      Increase the pin-count on the object by one.
      void read​(int position, byte[] b)
      Read a sequence of bytes into the provided byte-array.
      void read​(int position, byte[] b, int off, int len)
      Read a sequence of bytes into the provided byte-array, starting with the specified offset, and reading the specified number of bytes.
      boolean readBoolean​(int position)
      Reads and returns a Boolean value from the specified position.
      byte readByte​(int position)
      Reads and returns a signed byte from the specified position.
      char readChar​(int position)
      Reads and returns a two-byte char value from the specified position.
      java.time.LocalDate readDate​(int position)  
      java.time.LocalDateTime readDateTime​(int position)  
      double readDouble​(int position)  
      java.lang.String readFixedSizeString​(int position, int len)
      This method reads and returns a string whose length is fixed at a constant size.
      float readFloat​(int position)  
      int readInt​(int position)
      Reads and returns a 4-byte integer value from the specified position.
      long readLong​(int position)
      Reads and returns an 8-byte long integer value from the specified position.
      java.math.BigDecimal readNumeric​(int position)  
      java.lang.Object readObject​(int position, ColumnType colType)
      This method provides a higher-level wrapper around the other methods in the DBPage class, allowing object-values to be read, as long as the data-type is provided along with the object.
      short readShort​(int position)
      Reads and returns a signed short from the specified position.
      java.time.LocalTime readTime​(int position)  
      int readUnsignedByte​(int position)
      Reads and returns an unsigned byte from the specified position.
      long readUnsignedInt​(int position)
      Reads and returns a 4-byte unsigned integer value from the specified position.
      int readUnsignedShort​(int position)
      Reads and returns an unsigned short from the specified position.
      java.lang.String readVarString255​(int position)
      This method reads and returns a variable-length string whose maximum length is 255 bytes.
      java.lang.String readVarString65535​(int position)
      This method reads and returns a variable-length string whose maximum length is 65535 bytes.
      void setDataRange​(int position, int length, byte value)
      Write the specified alueMove the specified data region in the page.
      void setDirty​(boolean dirty)
      Sets the dirty flag to true or false, indicating whether the page's data has or has not been changed in memory.
      void setPageLSN​(LogSequenceNumber lsn)  
      void syncOldPageData()
      For a dirty page, this method copies the "new page data" into the "old page data" so that they are the same.
      java.lang.String toFormattedString()  
      java.lang.String toString()  
      void unpin()
      Decrease the pin-count on the object by one.
      void write​(int position, byte[] b)
      Write a sequence of bytes from a byte-array into the page.
      void write​(int position, byte[] b, int off, int len)
      Write a sequence of bytes from a byte-array into the page, starting with the specified offset in the buffer, and writing the specified number of bytes.
      void writeBoolean​(int position, boolean value)
      Writes a Boolean value to the specified position.
      void writeByte​(int position, int value)
      Writes a (signed or unsigned) byte to the specified position.
      void writeChar​(int position, int value)
      Writes a char to the specified position.
      void writeDate​(int position, java.time.LocalDate value)  
      void writeDateTime​(int position, java.time.LocalDateTime value)  
      void writeDouble​(int position, double value)  
      void writeFixedSizeString​(int position, java.lang.String value, int len)
      This method stores a string whose length is fixed at a constant size.
      void writeFloat​(int position, float value)  
      void writeInt​(int position, int value)
      Writes a 4-byte integer to the specified position.
      void writeLong​(int position, long value)
      Writes an 8-byte long integer to the specified position.
      void writeNumeric​(int position, java.math.BigDecimal value)  
      int writeObject​(int position, ColumnType colType, java.lang.Object value)
      This method provides a higher-level wrapper around the other methods in the DBPage class, allowing object-values to be stored, as long as the object isn't null and the data-type is provided along with the object.
      void writeShort​(int position, int value)
      Writes a (signed or unsigned) short to the specified position.
      void writeTime​(int position, java.time.LocalTime value)  
      void writeVarString255​(int position, java.lang.String value)
      This method stores a variable-length string whose maximum length is 255 bytes.
      void writeVarString65535​(int position, java.lang.String value)
      This method stores a variable-length string whose maximum length is 65535 bytes.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • logger

        private static org.apache.logging.log4j.Logger logger
        A logging object for reporting anything interesting that happens.
      • bufferManager

        private BufferManager bufferManager
        The buffer manager is used by this class to request buffer space when needed, so that a maximum cap can be placed on memory usage.
      • dbFile

        private DBFile dbFile
        A reference to the database file that this page is from.
      • pageNo

        private int pageNo
        The page number in the table file. A value of 0 is the first page in the file.
      • pinCount

        private java.util.concurrent.atomic.AtomicInteger pinCount
        The pin-count of this page. When nonzero, the page is not allowed to be flushed from the buffer manager since the page is being used by at least one session.
      • dirty

        private boolean dirty
        This flag is true if this page has been modified in memory.
      • pageLSN

        private LogSequenceNumber pageLSN
        For dirty pages, this field is set to the Log Sequence Number of the write-ahead log record corresponding to the most recent write to the page. When the page is being flushed back to disk, the write-ahead log must be written to at least this point, or else the write-ahead logging rule will be violated.
      • pageData

        private byte[] pageData
        The actual data for the table-page.
      • oldPageData

        private byte[] oldPageData
        When the page is marked dirty, this gets set to the original version of the page, so that we can properly record changes to the write-ahead log.
    • Constructor Detail

      • DBPage

        public DBPage​(BufferManager bufferManager,
                      DBFile dbFile,
                      int pageNo)
        Constructs a new, empty table-page for the specified table file. Note that the page data is not loaded into the object; that must be done in a separate step.
        Parameters:
        dbFile - The database file that this page is contained within.
        pageNo - The page number within the database file.
        Throws:
        java.lang.NullPointerException - if dbFile is null
        java.lang.IllegalArgumentException - if pageNo is negative
    • Method Detail

      • getDBFile

        public DBFile getDBFile()
        Returns the database file that this page is contained within.
        Returns:
        the database file that this page is contained within.
      • isFromDBFile

        public boolean isFromDBFile​(DBFile databaseFile)
        Returns true if this page is from the specified database file. This function simply uses DBFile.equals(java.lang.Object) for the comparison.
        Parameters:
        databaseFile - the database file to examine this page for membership
        Returns:
        true if the specified database file is the same as this DB file.
      • getPageNo

        public int getPageNo()
        Returns the page-number of this database page.
        Returns:
        the page-number of this database page
      • getPageSize

        public int getPageSize()
        Returns the page size in bytes.
        Returns:
        the page-size in bytes
      • pin

        public void pin()
        Description copied from interface: Pinnable
        Increase the pin-count on the object by one. An object with a nonzero pin-count cannot be released because it is in use.
        Specified by:
        pin in interface Pinnable
      • unpin

        public void unpin()
        Description copied from interface: Pinnable
        Decrease the pin-count on the object by one. When the pin-count reaches zero, the object can be released.
        Specified by:
        unpin in interface Pinnable
      • getPinCount

        public int getPinCount()
        Description copied from interface: Pinnable
        Returns the total number of times the object has been pinned.
        Specified by:
        getPinCount in interface Pinnable
        Returns:
        the total number of times the object has been pinned.
      • isPinned

        public boolean isPinned()
        Description copied from interface: Pinnable
        Returns true if the object is currently pinned, false otherwise.
        Specified by:
        isPinned in interface Pinnable
      • getPageData

        public byte[] getPageData()
        Returns the byte-array of the page's data. Note that if any changes are made to the page's data, the dirty-flag must be updated appropriately or else the data will not be written back to the file.
        Returns:
        a byte-array containing the page's data
      • getOldPageData

        public byte[] getOldPageData()
        Returns the byte-array of the page's data at the last point when the page became dirty, or null if the page is currently clean.
        Returns:
        a byte-array containing the last "clean" version of the page's data
      • syncOldPageData

        public void syncOldPageData()
        For a dirty page, this method copies the "new page data" into the "old page data" so that they are the same. This is necessary when changes are recorded to the write-ahead log; since the changes are reflected in the WAL, it's not necessary to represent the deltas anymore.
        Throws:
        java.lang.IllegalStateException - if the page is not currently marked dirty
      • isDirty

        public boolean isDirty()
        Returns true if the page's data has been changed in memory; false otherwise.
        Returns:
        true if the page's data has been changed in memory
      • setDirty

        public void setDirty​(boolean dirty)
        Sets the dirty flag to true or false, indicating whether the page's data has or has not been changed in memory.
        Parameters:
        dirty - the dirty flag; true if the page's data is dirty, or false otherwise
      • invalidate

        public void invalidate()
        This method makes the DBPage invalid by clearing all of its internal references. It is used by the Buffer Manager when a page is removed from the cache so that no other database code will continue to try to use the page.
      • read

        public void read​(int position,
                         byte[] b,
                         int off,
                         int len)
        Read a sequence of bytes into the provided byte-array, starting with the specified offset, and reading the specified number of bytes.
        Parameters:
        position - the starting index within the page to start reading data
        b - the destination buffer to save the data into
        off - the starting offset to save data to in the destination buffer
        len - the number of bytes to transfer to the destination buffer
      • read

        public void read​(int position,
                         byte[] b)
        Read a sequence of bytes into the provided byte-array. The entire array is filled from start to end.
        Parameters:
        position - the starting index within the page to start reading data
        b - the destination buffer to save the data into
      • write

        public void write​(int position,
                          byte[] b,
                          int off,
                          int len)
        Write a sequence of bytes from a byte-array into the page, starting with the specified offset in the buffer, and writing the specified number of bytes.
        Parameters:
        position - the starting index within the page to start writing data
        b - the source buffer to read the data from
        off - the starting offset to read data from the source buffer
        len - the number of bytes to transfer from the source buffer
      • write

        public void write​(int position,
                          byte[] b)
        Write a sequence of bytes from a byte-array into the page. The entire contents of the array is written to the page.
        Parameters:
        position - the starting index within the page to start writing data
        b - the source buffer to read the data from
      • moveDataRange

        public void moveDataRange​(int srcPosition,
                                  int dstPosition,
                                  int length)
        Move the specified data region in the page.
        Parameters:
        srcPosition - The source offset to copy data from.
        dstPosition - The destination offset to copy data to.
        length - The number of bytes of data to move.
      • setDataRange

        public void setDataRange​(int position,
                                 int length,
                                 byte value)
        Write the specified alueMove the specified data region in the page.
        Parameters:
        position - The starting position to write the value to.
        length - The number of bytes of data to set.
        value - The byte-value to write to the entire range.
      • readBoolean

        public boolean readBoolean​(int position)
        Reads and returns a Boolean value from the specified position. The Boolean value is encoded as a single byte; a zero value is interpreted as false, and a nonzero value is interpreted as true.
        Parameters:
        position - the starting location in the page to start reading the value from
        Returns:
        the Boolean value
      • writeBoolean

        public void writeBoolean​(int position,
                                 boolean value)
        Writes a Boolean value to the specified position. The Boolean value is encoded as a single byte; false is written as 0, and true is written as 1.
        Parameters:
        position - the location in the page to write the value to
        value - the Boolean value
      • readByte

        public byte readByte​(int position)
        Reads and returns a signed byte from the specified position.
        Parameters:
        position - the location in the page to read the value from
        Returns:
        the signed byte value
      • writeByte

        public void writeByte​(int position,
                              int value)
        Writes a (signed or unsigned) byte to the specified position. The byte value is specified as an integer for the sake of convenience (specifically to avoid having to cast an argument to a byte value), but the input is also truncated down to the low 8 bits.
        Parameters:
        position - the location in the page to write the value to
        value - the byte value
      • readUnsignedByte

        public int readUnsignedByte​(int position)
        Reads and returns an unsigned byte from the specified position. The value is returned as an int whose value will be between 0 and 255, inclusive.
        Parameters:
        position - the location in the page to read the value from
        Returns:
        the unsigned byte value, as an integer
      • readUnsignedShort

        public int readUnsignedShort​(int position)
        Reads and returns an unsigned short from the specified position. The value is returned as an int whose value will be between 0 and 65535, inclusive.
        Parameters:
        position - the location in the page to start reading the value from
        Returns:
        the unsigned short value, as an integer
      • readShort

        public short readShort​(int position)
        Reads and returns a signed short from the specified position. The value is returned as a short.
        Parameters:
        position - the location in the page to start reading the value from
        Returns:
        the signed short value
      • writeShort

        public void writeShort​(int position,
                               int value)
        Writes a (signed or unsigned) short to the specified position. The short value is specified as an integer for the sake of convenience (specifically to avoid having to cast an argument to a short value), but the input is also truncated down to the low 16 bits.
        Parameters:
        position - the location in the page to write the value to
        value - the byte value
      • readChar

        public char readChar​(int position)
        Reads and returns a two-byte char value from the specified position.
        Parameters:
        position - the location in the page to start reading the value from
        Returns:
        the char value
      • writeChar

        public void writeChar​(int position,
                              int value)
        Writes a char to the specified position. The char value is specified as an integer for the sake of convenience (specifically to avoid having to cast an argument to a char value), but the input is also truncated down to the low 16 bits.
        Parameters:
        position - the location in the page to write the value to
        value - the char value
      • readUnsignedInt

        public long readUnsignedInt​(int position)
        Reads and returns a 4-byte unsigned integer value from the specified position.
        Parameters:
        position - the location in the page to start reading the value from
        Returns:
        the unsigned integer value, as a long
      • readInt

        public int readInt​(int position)
        Reads and returns a 4-byte integer value from the specified position.
        Parameters:
        position - the location in the page to start reading the value from
        Returns:
        the signed int value
      • writeInt

        public void writeInt​(int position,
                             int value)
        Writes a 4-byte integer to the specified position.
        Parameters:
        position - the location in the page to write the value to
        value - the 4-byte integer value
      • readLong

        public long readLong​(int position)
        Reads and returns an 8-byte long integer value from the specified position.
        Parameters:
        position - the location in the page to start reading the value from
        Returns:
        the signed long value
      • writeLong

        public void writeLong​(int position,
                              long value)
        Writes an 8-byte long integer to the specified position.
        Parameters:
        position - the location in the page to write the value to
        value - the 8-byte long integer value
      • readFloat

        public float readFloat​(int position)
      • writeFloat

        public void writeFloat​(int position,
                               float value)
      • readDouble

        public double readDouble​(int position)
      • writeDouble

        public void writeDouble​(int position,
                                double value)
      • readVarString255

        public java.lang.String readVarString255​(int position)
        This method reads and returns a variable-length string whose maximum length is 255 bytes. The string is expected to be in US-ASCII encoding, so multibyte characters are not supported.

        The string's data format is expected to be a single unsigned byte b specifying the string's length, followed by b more bytes consisting of the string value itself.

        Parameters:
        position - the location in the page to start reading the value from
        Returns:
        a string object containing the stored value, up to a maximum of 255 characters in length
      • writeVarString255

        public void writeVarString255​(int position,
                                      java.lang.String value)
        This method stores a variable-length string whose maximum length is 255 bytes. The string is expected to be in US-ASCII encoding, so multibyte characters are not supported.

        The string is stored as a single unsigned byte b specifying the string's length, followed by b more bytes consisting of the string value itself.

        Parameters:
        position - the location in the page to start writing the value to
        value - the string object containing the data to store
        Throws:
        java.lang.NullPointerException - if value is null
        java.lang.IllegalArgumentException - if the input string is longer than 255 characters
      • readVarString65535

        public java.lang.String readVarString65535​(int position)
        This method reads and returns a variable-length string whose maximum length is 65535 bytes. The string is expected to be in US-ASCII encoding, so multibyte characters are not supported.

        The string's data format is expected to be a single unsigned short (two bytes) s specifying the string's length, followed by s more bytes consisting of the string value itself.

        Parameters:
        position - the location in the page to start reading the value from
        Returns:
        a string object containing the stored value, up to a maximum of 65535 characters in length
      • writeVarString65535

        public void writeVarString65535​(int position,
                                        java.lang.String value)
        This method stores a variable-length string whose maximum length is 65535 bytes. The string is expected to be in US-ASCII encoding, so multibyte characters are not supported.

        The string is stored as a single unsigned short s specifying the string's length, followed by s more bytes consisting of the string value itself.

        Parameters:
        position - the location in the page to start writing the value to
        value - the string object containing the data to store
        Throws:
        java.lang.NullPointerException - if value is null
        java.lang.IllegalArgumentException - if the input string is longer than 65535 characters
      • readFixedSizeString

        public java.lang.String readFixedSizeString​(int position,
                                                    int len)
        This method reads and returns a string whose length is fixed at a constant size. The string is expected to be in US-ASCII encoding, so multibyte characters are not supported.

        Strings shorter than the specified length are padded with 0 bytes at the end of the string, and this padding is removed when the string is read. The string's characters are stored starting with the specified position. If the string is shorter than the fixed length then the data is expected to be terminated with a \\u0000 (i.e. NUL) value. (If the string is exactly the given length then no string terminator is expected.) The implication of this storage format is that embedded NUL characters are not allowed with this storage format.

        Parameters:
        position - the location in the page to start reading the value from
        len - the length of the fixed-size string
        Returns:
        a string object containing the stored value, up to a maximum of len characters in length
      • writeFixedSizeString

        public void writeFixedSizeString​(int position,
                                         java.lang.String value,
                                         int len)
        This method stores a string whose length is fixed at a constant size. The string is expected to be in US-ASCII encoding, so multibyte characters are not supported.

        The string's characters are stored starting with the specified position. If the string is shorter than the fixed length then the data is padded with \\u0000 (i.e. NUL) values. If the string is exactly the given length then no string terminator is stored. The implication of this storage format is that embedded NUL characters are not allowed with this storage format.

        Parameters:
        position - the location in the page to start writing the value to
        value - the string object containing the data to store
        len - the number of bytes used to store the string field
        Throws:
        java.lang.NullPointerException - if value is null
        java.lang.IllegalArgumentException - if the input string is longer than len characters
      • readNumeric

        public java.math.BigDecimal readNumeric​(int position)
      • writeNumeric

        public void writeNumeric​(int position,
                                 java.math.BigDecimal value)
      • readDate

        public java.time.LocalDate readDate​(int position)
      • writeDate

        public void writeDate​(int position,
                              java.time.LocalDate value)
      • readTime

        public java.time.LocalTime readTime​(int position)
      • writeTime

        public void writeTime​(int position,
                              java.time.LocalTime value)
      • readDateTime

        public java.time.LocalDateTime readDateTime​(int position)
      • writeDateTime

        public void writeDateTime​(int position,
                                  java.time.LocalDateTime value)
      • readObject

        public java.lang.Object readObject​(int position,
                                           ColumnType colType)
        This method provides a higher-level wrapper around the other methods in the DBPage class, allowing object-values to be read, as long as the data-type is provided along with the object.
        Parameters:
        position - the location in the page to start reading the value from
        colType - the type of the value being read
        Returns:
        the object read from the data
        Throws:
        java.lang.NullPointerException - if colType or value is null
        java.lang.IllegalArgumentException - if the input string is longer than len characters
      • writeObject

        public int writeObject​(int position,
                               ColumnType colType,
                               java.lang.Object value)
        This method provides a higher-level wrapper around the other methods in the DBPage class, allowing object-values to be stored, as long as the object isn't null and the data-type is provided along with the object.
        Parameters:
        position - the location in the page to start writing the value to
        colType - the type of the value being stored
        value - the object containing the data to store
        Returns:
        the total number of bytes written in the operation; i.e. this is the amount that the position is advanced.
        Throws:
        java.lang.NullPointerException - if colType or value is null
        java.lang.IllegalArgumentException - if the input string is longer than len characters
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • toFormattedString

        public java.lang.String toFormattedString()
      • getChangesAsString

        public java.lang.String getChangesAsString()
        This helper method returns a formatted string describing all changes made to the page's contents; that is, the differences between the pageData and the oldPageData byte-arrays. The output is formatted to inclue rows of 32 bytes, and only includes rows where the data between old and new pages are actually different.
        Returns:
        a formatted string describing all changes made to the page's contents
        Throws:
        java.lang.IllegalStateException - if the method is called on a non-dirty page
      • close

        public void close()
        Specified by:
        close in interface java.lang.AutoCloseable