2 * Sixth Data. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
7 package eu.svjatoslav.sixth.data.store.file;
9 import java.io.IOException;
11 public class MetaData {
13 public static final int FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START = 4 * 6;
14 private static final int FORMAT_VERSION = 1;
15 private static final int FILE_LOCATION_VERSION = 4 * 0;
16 private static final int FILE_LOCATION_ENTRIES_TABLE_SIZE = 4 * 1;
17 private static final int FILE_LOCATION_USED_ENTRIES_COUNT = 4 * 2;
18 private static final int FILE_LOCATION_CURRENT_ENTRY = 4 * 3;
19 private static final int FILE_LOCATION_CURRENT_LOCATION = 4 * 4; // LONG!!
20 private final FileDataStore dataStore;
21 private int entriesTableSize;
22 private int currentEntry;
23 private int usedEntriesCount;
24 private long currentLocation;
26 public MetaData(final FileDataStore dataStore) {
27 this.dataStore = dataStore;
31 * @return address of the start of the allocated space
33 public synchronized long allocateStorageSpace(final int amountOfBytes) {
34 final long locationStart = currentLocation;
35 currentLocation += amountOfBytes;
39 public void decreaseUsedEntriesCount() {
43 public synchronized void ensureMinimumCurrentLocation(
44 final long minimumLocation) {
46 if (currentLocation < minimumLocation)
47 currentLocation = minimumLocation;
50 public boolean entriesTableNeedsIncreasing() {
51 final int reserveSize = (entriesTableSize / 10) + 1;
53 return usedEntriesCount >= (entriesTableSize - reserveSize);
57 public long getEntriesStorageAreaStart() {
58 return FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START
59 + (EntryRecord.ENTRY_RECORD_LENGTH * entriesTableSize);
62 public long getEntriesStorageAreaStart(
63 final int hypotheticalEntriesTableSize) {
64 return FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START
65 + (EntryRecord.ENTRY_RECORD_LENGTH * hypotheticalEntriesTableSize);
69 * @return amount of entries in the entries table
71 public int getEntriesTableSize() {
72 return entriesTableSize;
75 public void setEntriesTableSize(final int newSize) {
76 entriesTableSize = newSize;
79 public int getNewEntryId() {
82 if (currentEntry >= getEntriesTableSize())
88 public void increaseUsedEntriesCount() {
92 public void initializeNewFile() throws IOException {
93 entriesTableSize = 16;
95 currentEntry = entriesTableSize - 1;
96 currentLocation = getEntriesStorageAreaStart();
101 public void readFileHeader() throws IOException {
103 final int fileVersion = dataStore.readInt(FILE_LOCATION_VERSION);
104 if (fileVersion != FORMAT_VERSION)
105 throw new RuntimeException("File version is " + fileVersion
106 + " but version " + FORMAT_VERSION + " is required.");
108 entriesTableSize = dataStore.readInt(FILE_LOCATION_ENTRIES_TABLE_SIZE);
110 usedEntriesCount = dataStore.readInt(FILE_LOCATION_USED_ENTRIES_COUNT);
112 currentEntry = dataStore.readInt(FILE_LOCATION_CURRENT_ENTRY);
114 currentLocation = dataStore.readLong(FILE_LOCATION_CURRENT_LOCATION);
117 public void setCurrentLocation(final long currentLocation) {
118 this.currentLocation = currentLocation;
121 public void writeFileHeader() throws IOException {
122 dataStore.writeInt(FILE_LOCATION_VERSION, FORMAT_VERSION);
123 dataStore.writeInt(FILE_LOCATION_ENTRIES_TABLE_SIZE,
124 getEntriesTableSize());
125 dataStore.writeInt(FILE_LOCATION_USED_ENTRIES_COUNT, usedEntriesCount);
126 dataStore.writeInt(FILE_LOCATION_CURRENT_ENTRY, currentEntry);
127 dataStore.writeLong(FILE_LOCATION_CURRENT_LOCATION, currentLocation);