2 * Sixth - System for data storage, computation, exploration and interaction.
3 * Copyright ©2012-2016, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 3 of the GNU Lesser General Public License
7 * or later as published by the Free Software Foundation.
10 package eu.svjatoslav.sixth.data.store.file;
12 import java.io.IOException;
14 public class MetaData {
16 public static final int FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START = 4 * 6;
17 private static final int FORMAT_VERSION = 1;
18 private static final int FILE_LOCATION_VERSION = 4 * 0;
19 private static final int FILE_LOCATION_ENTRIES_TABLE_SIZE = 4 * 1;
20 private static final int FILE_LOCATION_USED_ENTRIES_COUNT = 4 * 2;
21 private static final int FILE_LOCATION_CURRENT_ENTRY = 4 * 3;
22 private static final int FILE_LOCATION_CURRENT_LOCATION = 4 * 4; // LONG!!
23 private final FileDataStore dataStore;
24 private int entriesTableSize;
25 private int currentEntry;
26 private int usedEntriesCount;
27 private long currentLocation;
29 public MetaData(final FileDataStore dataStore) {
30 this.dataStore = dataStore;
34 * @return address of the start of the allocated space
36 public synchronized long allocateStorageSpace(final int amountOfBytes) {
37 final long locationStart = currentLocation;
38 currentLocation += amountOfBytes;
42 public void decreaseUsedEntriesCount() {
46 public synchronized void ensureMinimumCurrentLocation(
47 final long minimumLocation) {
49 if (currentLocation < minimumLocation)
50 currentLocation = minimumLocation;
53 public boolean entriesTableNeedsIncreasing() {
54 final int reserveSize = (entriesTableSize / 10) + 1;
56 return usedEntriesCount >= (entriesTableSize - reserveSize);
60 public long getEntriesStorageAreaStart() {
61 return FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START
62 + (EntryRecord.ENTRY_RECORD_LENGTH * entriesTableSize);
65 public long getEntriesStorageAreaStart(
66 final int hypotheticalEntriesTableSize) {
67 return FILE_LOCATION_ENTRY_ALLOCATION_TABLE_START
68 + (EntryRecord.ENTRY_RECORD_LENGTH * hypotheticalEntriesTableSize);
72 * @return amount of entries in the entries table
74 public int getEntriesTableSize() {
75 return entriesTableSize;
78 public void setEntriesTableSize(final int newSize) {
79 entriesTableSize = newSize;
82 public int getNewEntryId() {
85 if (currentEntry >= getEntriesTableSize())
91 public void increaseUsedEntriesCount() {
95 public void initializeNewFile() throws IOException {
96 entriesTableSize = 16;
98 currentEntry = entriesTableSize - 1;
99 currentLocation = getEntriesStorageAreaStart();
104 public void readFileHeader() throws IOException {
106 final int fileVersion = dataStore.readInt(FILE_LOCATION_VERSION);
107 if (fileVersion != FORMAT_VERSION)
108 throw new RuntimeException("File version is " + fileVersion
109 + " but version " + FORMAT_VERSION + " is required.");
111 entriesTableSize = dataStore.readInt(FILE_LOCATION_ENTRIES_TABLE_SIZE);
113 usedEntriesCount = dataStore.readInt(FILE_LOCATION_USED_ENTRIES_COUNT);
115 currentEntry = dataStore.readInt(FILE_LOCATION_CURRENT_ENTRY);
117 currentLocation = dataStore.readLong(FILE_LOCATION_CURRENT_LOCATION);
120 public void setCurrentLocation(final long currentLocation) {
121 this.currentLocation = currentLocation;
124 public void writeFileHeader() throws IOException {
125 dataStore.writeInt(FILE_LOCATION_VERSION, FORMAT_VERSION);
126 dataStore.writeInt(FILE_LOCATION_ENTRIES_TABLE_SIZE,
127 getEntriesTableSize());
128 dataStore.writeInt(FILE_LOCATION_USED_ENTRIES_COUNT, usedEntriesCount);
129 dataStore.writeInt(FILE_LOCATION_CURRENT_ENTRY, currentEntry);
130 dataStore.writeLong(FILE_LOCATION_CURRENT_LOCATION, currentLocation);