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;
022:
023: import java.util.*;
024:
025: /**
026: * @persistent
027: */
028: class P2HashMapIterator implements Iterator {
029:
030: private P1HashElement i_current;
031:
032: private final P2HashMap i_map;
033: private int i_nextIndex;
034:
035: private P1HashElement i_previous;
036:
037: P2HashMapIterator(P2HashMap a_map) {
038: i_map = a_map;
039: i_nextIndex = -1;
040: getNextCurrent();
041: }
042:
043: private int currentIndex() {
044: if (i_current == null) {
045: return -1;
046: }
047: return i_current.i_hashCode & i_map.i_mask;
048: }
049:
050: private void getNextCurrent() {
051: i_previous = i_current;
052: i_current = (P1HashElement) nextElement();
053: if (i_current != null) {
054: i_current.checkActive();
055: }
056: }
057:
058: public boolean hasNext() {
059: synchronized (i_map.streamLock()) {
060: return i_current != null;
061: }
062: }
063:
064: public Object next() {
065: synchronized (i_map.streamLock()) {
066: i_map.checkActive();
067: Object ret = null;
068: if (i_current != null) {
069: ret = i_current.activatedKey(i_map
070: .elementActivationDepth());
071: }
072: getNextCurrent();
073: return ret;
074: }
075: }
076:
077: private P1ListElement nextElement() {
078: if (i_current != null && i_current.i_next != null) {
079: return i_current.i_next;
080: }
081: if (i_nextIndex <= currentIndex()) {
082: searchNext();
083: }
084: if (i_nextIndex >= 0) {
085: return i_map.i_table[i_nextIndex];
086: }
087: return null;
088: }
089:
090: public void remove() {
091: synchronized (i_map.streamLock()) {
092: i_map.checkActive();
093: if (i_previous != null) {
094: int index = i_previous.i_hashCode & i_map.i_mask;
095: if (index >= 0 && index < i_map.i_table.length) {
096: P1HashElement last = null;
097: P1HashElement phe = i_map.i_table[index];
098: while (phe != i_previous && phe != null) {
099: phe.checkActive();
100: last = phe;
101: phe = (P1HashElement) phe.i_next;
102: }
103: if (phe != null) {
104: i_map.i_size--;
105: if (last == null) {
106: i_map.i_table[index] = (P1HashElement) phe.i_next;
107: } else {
108: last.i_next = phe.i_next;
109: last.update();
110: }
111: i_map.modified();
112: phe.delete(i_map.i_deleteRemoved);
113: }
114: }
115: i_previous = null;
116: }
117: }
118: }
119:
120: private void searchNext() {
121: if (i_nextIndex > -2) {
122: while (++i_nextIndex < i_map.i_tableSize) {
123: if (i_map.i_table[i_nextIndex] != null) {
124: return;
125: }
126: }
127: i_nextIndex = -2;
128: }
129: }
130:
131: }
|