001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2002, Centre for Computational Geography
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.index.rtree.cachefs;
018:
019: import org.geotools.index.DataDefinition;
020: import org.geotools.index.TreeException;
021: import java.io.IOException;
022: import java.nio.channels.FileChannel;
023: import java.util.Iterator;
024: import java.util.Stack;
025:
026: /**
027: * DOCUMENT ME!
028: *
029: * @author Tommaso Nolli
030: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/shapefile/src/main/java/org/geotools/index/rtree/cachefs/Parameters.java $
031: */
032: public class Parameters {
033: private int maxNodeEntries;
034: private int minNodeEntries;
035: private short splitAlg;
036: private DataDefinition dataDef;
037: private FileChannel channel;
038: private Stack freePages;
039: private boolean forceChannel;
040: private NodeCache cache;
041: private long newNodeOffset;
042:
043: public Parameters() {
044: this .freePages = new Stack();
045: this .cache = new NodeCache();
046: }
047:
048: /**
049: * DOCUMENT ME!
050: *
051: */
052: public FileChannel getChannel() {
053: return channel;
054: }
055:
056: /**
057: * DOCUMENT ME!
058: *
059: */
060: public DataDefinition getDataDef() {
061: return dataDef;
062: }
063:
064: /**
065: * DOCUMENT ME!
066: *
067: */
068: public int getMaxNodeEntries() {
069: return maxNodeEntries;
070: }
071:
072: /**
073: * DOCUMENT ME!
074: *
075: */
076: public int getMinNodeEntries() {
077: return minNodeEntries;
078: }
079:
080: /**
081: * DOCUMENT ME!
082: *
083: */
084: public short getSplitAlg() {
085: return splitAlg;
086: }
087:
088: /**
089: * DOCUMENT ME!
090: *
091: * @param channel
092: */
093: public void setChannel(FileChannel channel) {
094: this .channel = channel;
095: }
096:
097: /**
098: * DOCUMENT ME!
099: *
100: * @param definition
101: */
102: public void setDataDef(DataDefinition definition) {
103: dataDef = definition;
104: }
105:
106: /**
107: * DOCUMENT ME!
108: *
109: * @param i
110: */
111: public void setMaxNodeEntries(int i) {
112: maxNodeEntries = i;
113: }
114:
115: /**
116: * DOCUMENT ME!
117: *
118: * @param i
119: */
120: public void setMinNodeEntries(int i) {
121: minNodeEntries = i;
122: }
123:
124: /**
125: * DOCUMENT ME!
126: *
127: * @param s
128: */
129: public void setSplitAlg(short s) {
130: splitAlg = s;
131: }
132:
133: /**
134: * DOCUMENT ME!
135: *
136: */
137: public boolean getForceChannel() {
138: return forceChannel;
139: }
140:
141: /**
142: * DOCUMENT ME!
143: *
144: * @param b
145: */
146: public void setForceChannel(boolean b) {
147: forceChannel = b;
148: }
149:
150: /**
151: * DOCUMENT ME!
152: *
153: */
154: public Stack getFreePages() {
155: return freePages;
156: }
157:
158: /**
159: * DOCUMENT ME!
160: *
161: * @param stack
162: */
163: public void setFreePages(Stack stack) {
164: freePages = stack;
165: }
166:
167: public synchronized void setNodeCacheSize(int size)
168: throws TreeException {
169: if (this .cache != null) {
170: this .flushCache();
171: }
172:
173: if (size == 0) {
174: this .cache = null;
175: } else if (size < 0) {
176: this .cache = new NodeCache();
177: } else {
178: this .cache = new NodeCache(size);
179: }
180: }
181:
182: /**
183: * Gets a <code>FileSystemNode</code> from the cache, if the node is non
184: * there, a new node will be created and added to the cache.
185: *
186: * @param offset The node offset
187: *
188: * @return a <code>FileSystemNode</code>
189: *
190: * @throws IOException
191: * @throws TreeException
192: */
193: public synchronized FileSystemNode getFromCache(long offset)
194: throws IOException, TreeException {
195: FileSystemNode node = null;
196:
197: if (this .cache != null) {
198: node = (FileSystemNode) this .cache.get(new Long(offset));
199: }
200:
201: if (node == null) {
202: node = new FileSystemNode(this , offset);
203: this .putToCache(node);
204: }
205:
206: return node;
207: }
208:
209: /**
210: * DOCUMENT ME!
211: *
212: * @param len
213: *
214: *
215: * @throws IOException DOCUMENT ME!
216: */
217: public synchronized long getNewNodeOffset(int len)
218: throws IOException {
219: long offset = 0L;
220:
221: if (this .newNodeOffset == 0L) {
222: offset = this .channel.size();
223: } else {
224: offset = this .newNodeOffset;
225: }
226:
227: this .newNodeOffset = offset + len;
228:
229: return offset;
230: }
231:
232: /**
233: * Soters a <code>FileSystemNode</code> in the cache.
234: *
235: * @param node the <code>FileSystemNode</code> to store
236: *
237: * @throws TreeException
238: */
239: public synchronized void putToCache(FileSystemNode node)
240: throws TreeException {
241: if (this .cache != null) {
242: // If we have a cache store the node, we'll flush it later
243: this .cache.put(new Long(node.getOffset()), node);
244: } else {
245: // Else flush the node to disk
246: node.flush();
247: }
248: }
249:
250: /**
251: * Removes a node from the cache
252: *
253: * @param node the node to remove
254: */
255: public synchronized void removeFromCache(FileSystemNode node) {
256: if (this .cache != null) {
257: this .cache.remove(node);
258: }
259: }
260:
261: /**
262: * Flushes all nodes and clears the cache
263: *
264: * @throws TreeException
265: */
266: public synchronized void flushCache() throws TreeException {
267: if (this .cache == null) {
268: return;
269: }
270:
271: Iterator iter = this .cache.keySet().iterator();
272:
273: while (iter.hasNext()) {
274: FileSystemNode element = (FileSystemNode) this.cache
275: .get(iter.next());
276: element.flush();
277: }
278:
279: this.cache.clear();
280: }
281: }
|