Class DBPage
- java.lang.Object
-
- edu.caltech.nanodb.storage.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 thepageData
and theoldPageData
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 theDBPage
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.
-
-
-
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 nulljava.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 usesDBFile.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.
-
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.
-
getPinCount
public int getPinCount()
Description copied from interface:Pinnable
Returns the total number of times the object has been pinned.- Specified by:
getPinCount
in interfacePinnable
- 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.
-
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
-
getPageLSN
public LogSequenceNumber getPageLSN()
-
setPageLSN
public void setPageLSN(LogSequenceNumber lsn)
-
invalidate
public void invalidate()
This method makes theDBPage
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 datab
- the destination buffer to save the data intooff
- the starting offset to save data to in the destination bufferlen
- 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 datab
- 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 datab
- the source buffer to read the data fromoff
- the starting offset to read data from the source bufferlen
- 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 datab
- 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 tovalue
- 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 tovalue
- 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 tovalue
- 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 tovalue
- 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 tovalue
- 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 tovalue
- 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 tovalue
- the string object containing the data to store- Throws:
java.lang.NullPointerException
- if value is nulljava.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 tovalue
- the string object containing the data to store- Throws:
java.lang.NullPointerException
- if value is nulljava.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 fromlen
- 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 tovalue
- the string object containing the data to storelen
- the number of bytes used to store the string field- Throws:
java.lang.NullPointerException
- if value is nulljava.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 fromcolType
- the type of the value being read- Returns:
- the object read from the data
- Throws:
java.lang.NullPointerException
- if colType or value is nulljava.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 tocolType
- the type of the value being storedvalue
- 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 nulljava.lang.IllegalArgumentException
- if the input string is longer than len characters
-
toString
public java.lang.String toString()
- Overrides:
toString
in classjava.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 thepageData
and theoldPageData
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 interfacejava.lang.AutoCloseable
-
-