001: /*
002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005:
006: package com.sun.portal.search.db;
007:
008: import com.sun.portal.search.util.*;
009: import com.sun.portal.search.rdm.*;
010: import com.sun.portal.log.common.PortalLogger;
011:
012: import com.sleepycat.db.*;
013:
014: import java.util.logging.Logger;
015: import java.util.logging.Level;
016:
017: /**
018: *
019: */
020: public class DbCursor {
021:
022: Dbc[] dbc;
023: RDMTransaction t;
024: PartitionedDb cdbm;
025: int current;
026:
027: // XXX THIS IS A MESS - need cursor per partition, need to close cursors on txb commit/abort
028:
029: /** Creates new DbCursor */
030: public DbCursor(PartitionedDb cdbm, RDMTransaction t, int flags)
031: throws RDMException {
032: try {
033: dbc = new Dbc[cdbm.extents];
034: this .t = t;
035: this .cdbm = cdbm;
036: current = 0;
037: for (int i = 0; i < dbc.length; ++i) {
038: DbTxn tx = null;
039: if (t != null)
040: tx = (DbTxn) t.getNativeTxn();
041: dbc[i] = cdbm.db[i].db.cursor(tx, flags);
042: }
043: } catch (DbException dbe) {
044: throw new RDMException(dbe);
045: }
046: }
047:
048: /** Creates new DbCursor */
049: private DbCursor() {
050: }
051:
052: /** not thread safe */
053: public void close() throws RDMException {
054: try {
055: for (int i = 0; i < dbc.length; ++i) {
056: if (dbc[i] != null) {
057: dbc[i].close();
058: dbc[i] = null;
059: }
060: }
061: } catch (DbException dbe) {
062: throw new RDMException(dbe);
063: }
064: }
065:
066: // returns: 0, Db.DB_KEYEMPTY, or throws error
067: public int get(Datum key, Datum data, int flags)
068: throws RDMException {
069: try {
070: if (flags == Db.DB_FIRST)
071: current = -1;
072: else {
073: int rcode = 0;
074: if (t != null)
075: rcode = dbc[current].get(key, data, Db.DB_NEXT); // XXX should probably use flags | DIRTY_READ
076: else {
077: for (;;) {
078: try {
079: rcode = dbc[current].get(key, data,
080: Db.DB_NEXT);
081: } catch (DbDeadlockException e) {
082: // Yes, this can happen, even without transactions
083: SearchLogger.getLogger().log(Level.FINE,
084: "PSSH_CSPSB0001");
085: continue;
086: }
087: break;
088: }
089: }
090: if (rcode == 0)
091: return 0;
092: }
093: // find next nonempty partition
094: for (++current; current < cdbm.extents; ++current) {
095: int rcode = 0;
096: if (t != null)
097: rcode = dbc[current].get(key, data, Db.DB_FIRST); // XXX should probably use flags | DIRTY_READ
098: else {
099: for (;;) {
100: try {
101: rcode = dbc[current].get(key, data,
102: Db.DB_FIRST);
103: } catch (DbDeadlockException e) {
104: // Yes, this can happen, even without transactions
105: SearchLogger.getLogger().log(Level.FINE,
106: "PSSH_CSPSB0001");
107: continue;
108: }
109: break;
110: }
111: }
112: if (rcode == 0)
113: return 0;
114: }
115: } catch (DbDeadlockException dbe) {
116: throw new RDMDeadlockException(dbe);
117: } catch (DbException dbe1) {
118: throw new RDMException(dbe1);
119: }
120: return Db.DB_NOTFOUND;
121: }
122:
123: // returns: 0, Db.DB_KEYEMPTY, or throws error
124: public int del(int flags) throws RDMException {
125: int rcode = 0;
126: try {
127: if (t != null)
128: rcode = dbc[current].del(flags);
129: else {
130: for (;;) {
131: try {
132: rcode = dbc[current].del(flags);
133: } catch (DbDeadlockException e) {
134: // Yes, this can happen, even without transactions
135: SearchLogger.getLogger().log(Level.FINE,
136: "PSSH_CSPSB0001");
137: continue;
138: }
139: break;
140: }
141: }
142: } catch (DbDeadlockException dbe) {
143: throw new RDMDeadlockException(dbe);
144: } catch (DbException dbe1) {
145: throw new RDMException(dbe1);
146: }
147: return rcode;
148: }
149:
150: // returns: 0, Db.DB_KEYEXIST, or throws error
151: public int put(Dbt key, Dbt data, int flags) throws RDMException {
152: int rcode = 0;
153: try {
154: if (t != null)
155: rcode = dbc[current].put(key, data, flags);
156: else {
157: for (;;) {
158: try {
159: rcode = dbc[current].put(key, data, flags);
160: } catch (DbDeadlockException e) {
161: // Yes, this can happen, even without transactions
162: SearchLogger.getLogger().log(Level.FINE,
163: "PSSH_CSPSB0001");
164: continue;
165: }
166: break;
167: }
168: }
169: } catch (DbDeadlockException dbe) {
170: throw new RDMDeadlockException(dbe);
171: } catch (DbException dbe1) {
172: throw new RDMException(dbe1);
173: }
174: return rcode;
175: }
176:
177: }
|