KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > objectserver > persistence > sleepycat > SleepycatCollectionsPersistor


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.objectserver.persistence.sleepycat;
5
6 import com.sleepycat.je.Cursor;
7 import com.sleepycat.je.CursorConfig;
8 import com.sleepycat.je.Database;
9 import com.sleepycat.je.DatabaseEntry;
10 import com.sleepycat.je.DatabaseException;
11 import com.sleepycat.je.LockMode;
12 import com.sleepycat.je.OperationStatus;
13 import com.tc.io.serializer.DSOSerializerPolicy;
14 import com.tc.io.serializer.TCObjectInputStream;
15 import com.tc.io.serializer.TCObjectOutputStream;
16 import com.tc.io.serializer.api.BasicSerializer;
17 import com.tc.logging.TCLogger;
18 import com.tc.object.ObjectID;
19 import com.tc.objectserver.persistence.api.PersistenceTransaction;
20 import com.tc.objectserver.persistence.sleepycat.SleepycatPersistor.SleepycatPersistorBase;
21 import com.tc.util.Conversion;
22
23 import java.io.ByteArrayInputStream JavaDoc;
24 import java.io.ByteArrayOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.ObjectInput JavaDoc;
27
28 public class SleepycatCollectionsPersistor extends SleepycatPersistorBase {
29
30   private final Database database;
31   private final BasicSerializer serializer;
32   private final ByteArrayOutputStream JavaDoc bao;
33   private final SleepycatCollectionFactory collectionFactory;
34   private final TCObjectOutputStream oo;
35
36   public SleepycatCollectionsPersistor(TCLogger logger, Database mapsDatabase,
37                                        SleepycatCollectionFactory sleepycatCollectionFactory) {
38     this.database = mapsDatabase;
39     this.collectionFactory = sleepycatCollectionFactory;
40     DSOSerializerPolicy policy = new DSOSerializerPolicy();
41     this.serializer = new BasicSerializer(policy);
42     this.bao = new ByteArrayOutputStream JavaDoc(1024);
43     this.oo = new TCObjectOutputStream(bao);
44   }
45
46   public void saveMap(PersistenceTransaction tx, SleepycatPersistableMap map) throws IOException JavaDoc, DatabaseException {
47     map.commit(this, tx, database);
48   }
49
50   public synchronized byte[] serialize(long id, Object JavaDoc o) throws IOException JavaDoc {
51     oo.writeLong(id);
52     serializer.serializeTo(o, oo);
53     oo.flush();
54     byte b[] = bao.toByteArray();
55     bao.reset();
56     return b;
57   }
58
59   public synchronized byte[] serialize(Object JavaDoc o) throws IOException JavaDoc {
60     serializer.serializeTo(o, oo);
61     oo.flush();
62     byte b[] = bao.toByteArray();
63     bao.reset();
64     return b;
65   }
66
67   public SleepycatPersistableMap loadMap(PersistenceTransaction tx, ObjectID id) throws IOException JavaDoc,
68       ClassNotFoundException JavaDoc, DatabaseException {
69     SleepycatPersistableMap map = (SleepycatPersistableMap) collectionFactory.createPersistentMap(id);
70     map.load(this, tx, database);
71     return map;
72   }
73
74   public Object JavaDoc deserialize(int start, byte[] data) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
75     if (start >= data.length) return null;
76     ByteArrayInputStream JavaDoc bai = new ByteArrayInputStream JavaDoc(data, start, data.length - start);
77     ObjectInput JavaDoc ois = new TCObjectInputStream(bai);
78     return serializer.deserializeFrom(ois);
79   }
80
81   public Object JavaDoc deserialize(byte[] data) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
82     return deserialize(0, data);
83   }
84
85   /**
86    * This method is slightly dubious in that it assumes that the ObjectID is the first 8 bytes of the Key in the entire
87    * collections database.(which is true, but that logic is spread elsewhere)
88    *
89    * @throws DatabaseException
90    */

91   public boolean deleteCollection(PersistenceTransaction tx, ObjectID id) throws DatabaseException {
92     // XXX:: Since we read in one direction and since we have to read the first record of the next map to break out, we
93
// need this to avoid deadlocks between commit thread and GC thread. Hence READ_COMMITTED
94
Cursor c = database.openCursor(pt2nt(tx), CursorConfig.READ_COMMITTED);
95     try {
96       boolean found = false;
97       byte idb[] = Conversion.long2Bytes(id.toLong());
98       DatabaseEntry key = new DatabaseEntry();
99       key.setData(idb);
100       DatabaseEntry value = new DatabaseEntry();
101       value.setPartial(0, 0, true);
102       if (c.getSearchKeyRange(key, value, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
103         do {
104           if (partialMatch(idb, key.getData())) {
105             found = true;
106             c.delete();
107           } else {
108             break;
109           }
110         } while (c.getNext(key, value, LockMode.DEFAULT) == OperationStatus.SUCCESS);
111       }
112       return found;
113     } finally {
114       c.close();
115     }
116   }
117
118   private boolean partialMatch(byte[] idbytes, byte[] key) {
119     if (key.length < idbytes.length) return false;
120     for (int i = 0; i < idbytes.length; i++) {
121       if (idbytes[i] != key[i]) return false;
122     }
123     return true;
124   }
125
126 }
127
Popular Tags