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.ix;
022:
023: import com.db4o.foundation.*;
024: import com.db4o.internal.*;
025:
026: /**
027: * Index root holder for a field and a transaction.
028: * @exclude
029: */
030: public class IndexTransaction implements Visitor4 {
031:
032: final Index4 i_index;
033: final LocalTransaction i_trans;
034: int i_version;
035: private Tree i_root;
036:
037: IndexTransaction(LocalTransaction a_trans, Index4 a_index) {
038: i_trans = a_trans;
039: i_index = a_index;
040: }
041:
042: /**
043: * Will raise an exception if argument class doesn't match this class - violates equals() contract in favor of failing fast.
044: */
045: public boolean equals(Object obj) {
046: if (this == obj) {
047: return true;
048: }
049: if (null == obj) {
050: return false;
051: }
052: if (getClass() != obj.getClass()) {
053: Exceptions4.shouldNeverHappen();
054: }
055: return i_trans == ((IndexTransaction) obj).i_trans;
056: }
057:
058: public int hashCode() {
059: return i_trans.hashCode();
060: }
061:
062: /**
063: */
064: public void add(int id, Object value) {
065: patch(new IxAdd(this , id, value));
066: }
067:
068: public void remove(int id, Object value) {
069: patch(new IxRemove(this , id, value));
070: }
071:
072: private void patch(IxPatch patch) {
073: i_root = Tree.add(i_root, patch);
074: }
075:
076: // public void add(IxPatch a_patch){
077: // i_root = Tree.add(i_root, a_patch);
078: // }
079:
080: public Tree getRoot() {
081: return i_root;
082: }
083:
084: public void commit() {
085: i_index.commit(this );
086: }
087:
088: public void rollback() {
089: i_index.rollback(this );
090: }
091:
092: void merge(IndexTransaction a_ft) {
093: Tree otherRoot = a_ft.getRoot();
094: if (otherRoot != null) {
095: otherRoot.traverseFromLeaves(this );
096: }
097: }
098:
099: /**
100: * Visitor functionality for merge:<br>
101: * Add
102: */
103: public void visit(Object obj) {
104: if (obj instanceof IxPatch) {
105: IxPatch tree = (IxPatch) obj;
106: if (tree.hasQueue()) {
107: Queue4 queue = tree.detachQueue();
108: while ((tree = (IxPatch) queue.next()) != null) {
109: tree.detachQueue();
110: addPatchToRoot(tree);
111: }
112: } else {
113: addPatchToRoot(tree);
114: }
115: }
116: }
117:
118: private void addPatchToRoot(IxPatch tree) {
119: if (tree._version != i_version) {
120: tree.beginMerge();
121: tree.handler().prepareComparison(
122: IxDeprecationHelper.comparableObject(
123: tree.handler(), i_trans, tree._value));
124: if (i_root == null) {
125: i_root = tree;
126: } else {
127: i_root = i_root.add(tree);
128: }
129: }
130: }
131:
132: int countLeaves() {
133: if (i_root == null) {
134: return 0;
135: }
136: final int[] leaves = { 0 };
137: i_root.traverse(new Visitor4() {
138: public void visit(Object a_object) {
139: leaves[0]++;
140: }
141: });
142: return leaves[0];
143: }
144:
145: public void setRoot(Tree a_tree) {
146: i_root = a_tree;
147: }
148:
149: public String toString() {
150: final StringBuffer sb = new StringBuffer();
151: sb.append("IxFieldTransaction ");
152: sb.append(System.identityHashCode(this ));
153: if (i_root == null) {
154: sb.append("\n Empty");
155: } else {
156: i_root.traverse(new Visitor4() {
157: public void visit(Object a_object) {
158: sb.append("\n");
159: sb.append(a_object.toString());
160: }
161: });
162: }
163: return sb.toString();
164: }
165:
166: }
|