2 * Sixth Data. Copyright ©2012-2018, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public License
6 * or later as published by the Free Software Foundation.
9 package eu.svjatoslav.sixth.data.store.file;
11 import java.io.IOException;
13 public class MetaData {
15 public static final int FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START = 4 * 6;
16 private static final int FORMAT_VERSION = 1;
17 private static final int FILE_LOCATION_VERSION = 4 * 0;
18 private static final int FILE_LOCATION_ENTRIES_TABLE_SIZE = 4 * 1;
19 private static final int FILE_LOCATION_USED_ENTRIES_COUNT = 4 * 2;
20 private static final int FILE_LOCATION_CURRENT_ENTRY = 4 * 3;
21 private static final int FILE_LOCATION_CURRENT_LOCATION = 4 * 4; // LONG!!
22 private final FileDataStore dataStore;
23 private int entriesTableSize;
24 private int currentEntry;
25 private int usedEntriesCount;
26 private long currentLocation;
28 public MetaData(final FileDataStore dataStore) {
29 this.dataStore = dataStore;
33 * @return address of the start of the allocated space
35 public synchronized long allocateStorageSpace(final int amountOfBytes) {
36 final long locationStart = currentLocation;
37 currentLocation += amountOfBytes;
41 public void decreaseUsedEntriesCount() {
45 public synchronized void ensureMinimumCurrentLocation(
46 final long minimumLocation) {
48 if (currentLocation < minimumLocation)
49 currentLocation = minimumLocation;
52 public boolean entriesTableNeedsIncreasing() {
53 final int reserveSize = (entriesTableSize / 10) + 1;
55 return usedEntriesCount >= (entriesTableSize - reserveSize);
59 public long getEntriesStorageAreaStart() {
60 return FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START
61 + (EntryRecord.ENTRY_RECORD_LENGTH * entriesTableSize);
64 public long getEntriesStorageAreaStart(
65 final int hypotheticalEntriesTableSize) {
66 return FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START
67 + (EntryRecord.ENTRY_RECORD_LENGTH * hypotheticalEntriesTableSize);
71 * @return amount of entries in the entries table
73 public int getEntriesTableSize() {
74 return entriesTableSize;
77 public void setEntriesTableSize(final int newSize) {
78 entriesTableSize = newSize;
81 public int getNewEntryId() {
84 if (currentEntry >= getEntriesTableSize())
90 public void increaseUsedEntriesCount() {
94 public void initializeNewFile() throws IOException {
95 entriesTableSize = 16;
97 currentEntry = entriesTableSize - 1;
98 currentLocation = getEntriesStorageAreaStart();
103 public void readFileHeader() throws IOException {
105 final int fileVersion = dataStore.readInt(FILE_LOCATION_VERSION);
106 if (fileVersion != FORMAT_VERSION)
107 throw new RuntimeException("File version is " + fileVersion
108 + " but version " + FORMAT_VERSION + " is required.");
110 entriesTableSize = dataStore.readInt(FILE_LOCATION_ENTRIES_TABLE_SIZE);
112 usedEntriesCount = dataStore.readInt(FILE_LOCATION_USED_ENTRIES_COUNT);
114 currentEntry = dataStore.readInt(FILE_LOCATION_CURRENT_ENTRY);
116 currentLocation = dataStore.readLong(FILE_LOCATION_CURRENT_LOCATION);
119 public void setCurrentLocation(final long currentLocation) {
120 this.currentLocation = currentLocation;
123 public void writeFileHeader() throws IOException {
124 dataStore.writeInt(FILE_LOCATION_VERSION, FORMAT_VERSION);
125 dataStore.writeInt(FILE_LOCATION_ENTRIES_TABLE_SIZE,
126 getEntriesTableSize());
127 dataStore.writeInt(FILE_LOCATION_USED_ENTRIES_COUNT, usedEntriesCount);
128 dataStore.writeInt(FILE_LOCATION_CURRENT_ENTRY, currentEntry);
129 dataStore.writeLong(FILE_LOCATION_CURRENT_LOCATION, currentLocation);