package org.basex.core;
import static org.basex.core.Text.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.basex.data.Data;
import org.basex.util.TokenBuilder;
import org.basex.util.Util;
/**
* This class organizes all currently opened database.
*
* @author BaseX Team 2005-12, BSD License
* @author Andreas Weiler
*/
public final class Datas {
/** List for data and pins. */
private final List<PData> list =
Collections.synchronizedList(new ArrayList<PData>());
/**
* Pins and returns an existing data reference for the specified database, or
* returns {@code null}.
* @param db name of the database
* @return data reference
*/
synchronized Data pin(final String db) {
for(final PData d : list) {
if(d.data.meta.name.equals(db)) {
d.pins++;
return d.data;
}
}
return null;
}
/**
* Unpins a data reference.
* @param data data reference
* @return true if reference was removed from the pool
*/
synchronized boolean unpin(final Data data) {
for(final PData d : list) {
if(d.data == data) {
final boolean close = --d.pins == 0;
if(close) list.remove(d);
return close;
}
}
return false;
}
/**
* Checks if the specified database is pinned.
* @param db name of the database
* @return result of check
*/
synchronized boolean pinned(final String db) {
for(final PData d : list) if(d.data.meta.name.equals(db)) return true;
return false;
}
/**
* Adds a data reference to the pool.
* @param d data reference
*/
synchronized void add(final Data d) {
list.add(new PData(d));
}
/**
* Returns the number of opened databases.
* @return number of databases
*/
public synchronized int size() {
return list.size();
}
/**
* Returns information on the opened database instances.
* @return data reference
*/
public String info() {
final TokenBuilder tb = new TokenBuilder();
tb.addExt(OPENED_DB_X, list.size());
tb.add(!list.isEmpty() ? COL : DOT);
for(final PData d : list) {
tb.add(NL + LI + d.data.meta.name + " (" + d.pins + "x)");
}
return tb.toString();
}
/**
* Closes all data references.
*/
synchronized void close() {
for(final PData d : list) {
try { d.data.close(); } catch(final IOException ex) { Util.debug(ex); }
}
list.clear();
}
/**
* Returns the number of pins for the specified database, or 0. Used for
* testing.
* @param db name of the database
* @return number of references
*/
public synchronized int pins(final String db) {
for(final PData d : list) {
if(d.data.meta.name.equals(db)) return d.pins;
}
return 0;
}
/**
* Inner class for a data object in the pool.
*
* @author BaseX Team 2005-12, BSD License
* @author Andreas Weiler
*/
private static final class PData {
/** Data reference. */
final Data data;
/** Number of current database users. */
int pins = 1;
/**
* Default constructor.
* @param d data reference
*/
PData(final Data d) {
data = d;
}
}
}