001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal.freespace;
022:
023: import com.db4o.*;
024: import com.db4o.foundation.*;
025: import com.db4o.internal.*;
026: import com.db4o.internal.slots.*;
027:
028: public abstract class AbstractFreespaceManager implements
029: FreespaceManager {
030:
031: final LocalObjectContainer _file;
032:
033: public static final byte FM_DEBUG = 127;
034: public static final byte FM_DEFAULT = 0;
035: public static final byte FM_LEGACY_RAM = 1;
036: public static final byte FM_RAM = 2;
037: public static final byte FM_IX = 3;
038: public static final byte FM_BTREE = 4;
039:
040: private static final int INTS_IN_SLOT = 12;
041:
042: public AbstractFreespaceManager(LocalObjectContainer file) {
043: _file = file;
044: }
045:
046: public static byte checkType(byte systemType) {
047: if (systemType == FM_DEFAULT) {
048: return FM_RAM;
049: }
050: return systemType;
051: }
052:
053: public static AbstractFreespaceManager createNew(
054: LocalObjectContainer file) {
055: return createNew(file, file.systemData().freespaceSystem());
056: }
057:
058: public abstract int onNew(LocalObjectContainer file);
059:
060: public static AbstractFreespaceManager createNew(
061: LocalObjectContainer file, byte systemType) {
062: systemType = checkType(systemType);
063: switch (systemType) {
064: case FM_IX:
065: return new FreespaceManagerIx(file);
066: case FM_BTREE:
067: return new BTreeFreespaceManager(file);
068: default:
069: return new RamFreespaceManager(file);
070: }
071: }
072:
073: public static int initSlot(LocalObjectContainer file) {
074: int address = file.getSlot(slotLength()).address();
075: slotEntryToZeroes(file, address);
076: return address;
077: }
078:
079: public void migrateTo(final FreespaceManager fm) {
080: traverse(new Visitor4() {
081: public void visit(Object obj) {
082: fm.free((Slot) obj);
083: }
084: });
085: }
086:
087: static void slotEntryToZeroes(LocalObjectContainer file, int address) {
088: StatefulBuffer writer = new StatefulBuffer(file
089: .systemTransaction(), address, slotLength());
090: for (int i = 0; i < INTS_IN_SLOT; i++) {
091: writer.writeInt(0);
092: }
093: if (Debug.xbytes) {
094: writer.setID(Const4.IGNORE_ID); // no XBytes check
095: }
096: writer.writeEncrypt();
097: }
098:
099: final static int slotLength() {
100: return Const4.INT_LENGTH * INTS_IN_SLOT;
101: }
102:
103: public int totalFreespace() {
104: final IntByRef mint = new IntByRef();
105: traverse(new Visitor4() {
106: public void visit(Object obj) {
107: Slot slot = (Slot) obj;
108: mint.value += slot.length();
109: }
110: });
111: return mint.value;
112: }
113:
114: public abstract void beginCommit();
115:
116: protected final int blockedDiscardLimit() {
117: return _file.blocksToBytes(discardLimit());
118: }
119:
120: protected int discardLimit() {
121: return _file.configImpl().discardFreeSpace();
122: }
123:
124: final boolean canDiscard(int blocks) {
125: return blocks == 0 || blocks < blockedDiscardLimit();
126: }
127:
128: public static void migrate(FreespaceManager oldFM,
129: FreespaceManager newFM) {
130: oldFM.migrateTo(newFM);
131: oldFM.freeSelf();
132: newFM.beginCommit();
133: newFM.endCommit();
134: }
135:
136: public void debugCheckIntegrity() {
137: final IntByRef lastStart = new IntByRef();
138: final IntByRef lastEnd = new IntByRef();
139: traverse(new Visitor4() {
140: public void visit(Object obj) {
141: Slot slot = (Slot) obj;
142: if (slot.address() <= lastEnd.value) {
143: throw new IllegalStateException();
144: }
145: lastStart.value = slot.address();
146: lastEnd.value = slot.address() + slot.length();
147: }
148: });
149:
150: }
151:
152: protected final LocalTransaction transaction() {
153: return (LocalTransaction) _file.systemTransaction();
154: }
155:
156: }
|