Implemented buffer

Signed-off-by: Jim Martens <github@2martens.de>
This commit is contained in:
2017-05-19 12:43:10 +02:00
parent fecafaf6c7
commit 14ebb872ac

View File

@ -1,63 +1,147 @@
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import java.util.*;
/** /**
* Persistence manager using the Singleton pattern. * Persistence manager using the Singleton pattern.
*/ */
public class PersistenceManager public class PersistenceManager {
{ private final static PersistenceManager instance;
private final static PersistenceManager instance; private Hashtable<Integer, String> _pageBuffer;
private Hashtable<Integer, Set<Integer>> _transactionPageBuffer;
private Hashtable<Integer, Boolean> _transactions;
private Hashtable<Integer, Integer> _pageLSN;
private int _nextTransactionNumber;
private int _nextLogSequenceNumber;
static { static {
try { try {
instance = new PersistenceManager(); instance = new PersistenceManager();
} } catch (Throwable e) {
catch (Throwable e) {
throw new RuntimeException(e.getMessage()); throw new RuntimeException(e.getMessage());
} }
} }
/** /**
* Returns an instance of the persistence manager. * Returns an instance of the persistence manager.
*
* @return instance * @return instance
*/ */
@Contract(pure = true) @Contract(pure = true)
public static PersistenceManager getInstance() public static PersistenceManager getInstance() {
{
return instance; return instance;
} }
/** /**
* private constructor * private constructor
*/ */
private PersistenceManager() private PersistenceManager() {
{} _pageBuffer = new Hashtable<>();
_transactionPageBuffer = new Hashtable<>();
_transactions = new Hashtable<>();
_pageLSN = new Hashtable<>();
_nextTransactionNumber = 1;
_nextLogSequenceNumber = 1;
}
/** /**
* Begins the transaction and returns the transaction ID. * Begins the transaction and returns the transaction ID.
*
* @return transaction ID * @return transaction ID
*/ */
public int beginTransaction() public int beginTransaction() {
{ _transactions.put(_nextTransactionNumber, false);
return 0; // return the next transaction number and increase it by one afterwards
return _nextTransactionNumber++;
} }
/** /**
* Commits the transaction specified by given ID. * Commits the transaction specified by given ID.
* @param taid transaction ID *
* @param taid
* transaction ID
*/ */
public void commit(int taid) public void commit(int taid) {
{ if (!_transactions.containsKey(taid)) {
throw new IllegalArgumentException("No transaction with given ID exists.");
}
// only perform commit actions if transaction isn't commited yet
if (!_transactions.get(taid)) {
_transactions.replace(taid, true);
}
} }
/** /**
* Writes given data into given page in given transaction. * Writes given data into given page in given transaction.
* @param taid transaction ID *
* @param pageid page ID * @param taid
* @param data data * transaction ID
* @param pageid
* page ID
* @param data
* data
*/ */
public void write(int taid, int pageid, String data) public void write(int taid, int pageid, String data) {
{ if (!_transactions.containsKey(taid)) {
throw new IllegalArgumentException("No transaction with given ID exists.");
}
if (_transactions.get(taid)) {
throw new IllegalArgumentException("Write operations cannot be performed for committed transactions.");
}
Set<Integer> pageIDs = _transactionPageBuffer.getOrDefault(taid, new HashSet<>());
pageIDs.add(pageid);
_transactionPageBuffer.put(taid, pageIDs);
_pageBuffer.put(pageid, data);
// log changes
int lsn = log(taid, pageid, data);
_pageLSN.put(pageid, lsn);
// call persist
persist();
}
/**
* Logs the necessary information to the log file.
*
* @param taid
* affected transaction
* @param pageid
* modified page
* @param data
* written data
* @return log sequence number
*/
private int log(int taid, int pageid, String data) {
return _nextLogSequenceNumber++;
}
/**
* Checks for full buffer and persists data of committed transactions to storage if buffer is full.
*/
private void persist() {
if (_pageBuffer.size() <= 5) {
return;
}
// TODO persist the data of committed transactions
Enumeration<Integer> transactionIDs = _transactions.keys();
List<Integer> commitedTransactions = new ArrayList<>();
while (transactionIDs.hasMoreElements()) {
Integer taid = transactionIDs.nextElement();
boolean committed = _transactions.get(taid);
if (committed) {
commitedTransactions.add(taid);
}
}
for (int taid : commitedTransactions) {
// TODO persist data of committed transaction
Set<Integer> pageIDs = _transactionPageBuffer.get(taid);
for (int pageid : pageIDs) {
// TODO persist data of pageID
_pageBuffer.remove(pageid);
}
_transactionPageBuffer.remove(taid);
_transactions.remove(taid);
}
} }
} }