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.cs;
022:
023: import com.db4o.*;
024: import com.db4o.foundation.*;
025: import com.db4o.internal.*;
026:
027: public class ClientTransactionPool {
028:
029: private final Hashtable4 _transaction2Container; // Transaction -> ContainerCount
030:
031: private final Hashtable4 _fileName2Container; // String -> ContainerCount
032:
033: private final LocalObjectContainer _mainContainer;
034:
035: private boolean _closed;
036:
037: public ClientTransactionPool(LocalObjectContainer mainContainer) {
038: ContainerCount mainEntry = new ContainerCount(mainContainer, 1);
039: _transaction2Container = new Hashtable4();
040: _fileName2Container = new Hashtable4();
041: _fileName2Container.put(mainContainer.fileName(), mainEntry);
042: _mainContainer = mainContainer;
043: }
044:
045: public Transaction acquireMain() {
046: return acquire(_mainContainer.fileName());
047: }
048:
049: public Transaction acquire(String fileName) {
050: synchronized (_mainContainer.lock()) {
051: ContainerCount entry = (ContainerCount) _fileName2Container
052: .get(fileName);
053: if (entry == null) {
054: LocalObjectContainer container = (LocalObjectContainer) Db4o
055: .openFile(fileName);
056: container.configImpl().setMessageRecipient(
057: _mainContainer.configImpl().messageRecipient());
058: entry = new ContainerCount(container);
059: _fileName2Container.put(fileName, entry);
060: }
061: Transaction transaction = entry.newTransaction();
062: _transaction2Container.put(transaction, entry);
063: return transaction;
064: }
065: }
066:
067: public void release(Transaction transaction, boolean rollbackOnClose) {
068: transaction.close(rollbackOnClose);
069: synchronized (_mainContainer.lock()) {
070: ContainerCount entry = (ContainerCount) _transaction2Container
071: .get(transaction);
072: _transaction2Container.remove(transaction);
073: entry.release();
074: if (entry.isEmpty()) {
075: _fileName2Container.remove(entry.fileName());
076: entry.close();
077: }
078: }
079: }
080:
081: public void close() {
082: synchronized (_mainContainer.lock()) {
083: Iterator4 entryIter = _fileName2Container.iterator();
084: while (entryIter.moveNext()) {
085: Entry4 hashEntry = (Entry4) entryIter.current();
086: ((ContainerCount) hashEntry.value()).close();
087: }
088: _closed = true;
089: }
090: }
091:
092: public int openFileCount() {
093: return isClosed() ? 0 : _fileName2Container.size();
094: }
095:
096: public boolean isClosed() {
097: return _closed == true || _mainContainer.isClosed();
098: }
099:
100: private static class ContainerCount {
101: private LocalObjectContainer _container;
102: private int _count;
103:
104: public ContainerCount(LocalObjectContainer container) {
105: this (container, 0);
106: }
107:
108: public ContainerCount(LocalObjectContainer container, int count) {
109: _container = container;
110: _count = count;
111: }
112:
113: public boolean isEmpty() {
114: return _count <= 0;
115: }
116:
117: public Transaction newTransaction() {
118: _count++;
119: return _container.newUserTransaction();
120: }
121:
122: public void release() {
123: if (_count == 0) {
124: throw new IllegalStateException();
125: }
126: _count--;
127: }
128:
129: public String fileName() {
130: return _container.fileName();
131: }
132:
133: public void close() {
134: _container.close();
135: _container = null;
136: }
137:
138: public int hashCode() {
139: return fileName().hashCode();
140: }
141:
142: public boolean equals(Object obj) {
143: if (this == obj)
144: return true;
145: if (obj == null || getClass() != obj.getClass())
146: return false;
147: final ContainerCount other = (ContainerCount) obj;
148: return fileName().equals(other.fileName());
149: }
150:
151: }
152: }
|