Below BerkeleyDBStorageDemo class is one possible extension for CORK Storage system. The code is ready to run.
1 /
2 * BerkeleyDBStorageDemo is a Storage implementation that stores
3 * serialized objects into the Berekeley DB. One object is stored in each
4 * node of Btree with object id.
5 *
6 * We assume for now that something higher-level (e.g., a Cache object)
7 * will only tell us to write the object when it needs to (i.e., rather
8 * than after every change). Hence this implementation writes
9 * immediately on a put. Similarly, we do no caching of objects for get()
10 * operations.
11 *
12 * $Id: BerkeleyDBStorageDemo.java,v 1.5 2002/08/19 11:20 kikim Exp $
13
14 * See the file LICENSE for redistribution information.
15
16 * Copyright (c) 1997-2001
17 * Sleepycat Software. All rights reserved.
18
19 * Implementation of the Storage interface that uses the GPL'd JSX classes:
20 *
21 * http://www.csse.monash.edu.au/~bren/JSX/
22 *
23 * to save and restore objects as XML files.
24 */
25 package edu.vt.cs.collab.cork.storage;
26 import com.sleepycat.db.*;
27 import java.io.File;
28 import java.io.FileNotFoundException;
29 import java.io.InputStreamReader;
30 import java.io.IOException;
31 import java.io.PrintStream;
32 import java.io.*;
33 import java.util.Enumeration;
34 import java.util.Vector;
35 import JSX.*;
36 import edu.vt.cs.collab.cork.*;
37 public class BerkeleyDBStorageDemo implements Serializable, Storage
38 {
39 /
40 * Nonvolatile persistent object storage file name.
41 * table is database handle
42 */
43 private static final String FileName = "BDBCorkTest.db";
44 private Db table;
45 /
46 * Constructs a new BerkeleyDBStorage object.
47 * Create database handler and set flags for retrieving values by key.
48 * Also set error stream and prefix for error messages.
49 * Open database with the specified mode
50 *
51 */
52 public BerkeleyDBStorageDemo()
53 {
54 try
55 {
56 table = new Db(null, 0);
57 table.set_flags(Db.DB_RECNUM);
58 table.set_error_stream(System.err);
59 table.set_errpfx("BDBCorkTest");
60 table.open(FileName, null, Db.DB_BTREE, Db.DB_CREATE, 0644);
61 }
62 catch (DbException dbe)
63 {
64 System.out.println(dbe.toString());
65 }
66 catch(IOException ioe)
67 {
68 System.out.println(ioe.toString());
69 }
70 }
71 /
72 * Here's an example of how we can extend a Dbt(Berkeley DB data structure)
73 * in a straightforward way to allow easy storage/retrieval of objects, or
74 * whatever kind of data you wish. We've declared it as a static inner
75 * class, but it need not be.
76 */
77 static class ObjectDbt extends Dbt
78 {
79 ObjectDbt()
80 {
81 set_flags(Db.DB_DBT_MALLOC); // Berekeley DB allocates a properly sized byte array
82 // to contain the data.
83 }
84 /
85 * Using Object Byte Streams, serialize the object
86 * then create XML output using JSX API
87 * then transform XML output into Dbt(Berkeley DB data structure).
88 */
89 ObjectDbt(Object obj)
90 {
91 try
92 {
93 ByteArrayOutputStream baos = new ByteArrayOutputStream();
94 ObjOut out = new ObjOut(baos); //using JSX API
95 out.writeObject(obj);
96 out.flush();
97 byte[] outbytes = baos.toByteArray();
98 out.close();
99 set_data(outbytes);
100 set_size(outbytes.length);
101 }
102 catch(IOException ioe)
103 {
104 System.out.println(ioe.toString());
105 }
106 }//ObjectDbt(Object obj);
107 }// Class ObjectDbt
108 /
109 * Puts the specified element into the Storage object, using the specified
110 * key. The element may be retrieved by doing a get() with the same
111 * key. The key and the element cannot be null.
112 * @param key the specified object id
113 * @param value the specified element
114 * @return the old value of the key, or null if it did not have one.
115 * @exception NullPointerException If the value of the specified element is null.
116 * @see Storage#get
117 */
118 public Object put(ObjectID key, Object value)
119 {
120 /*
121 * Doing this here so that at least we won't blow away a file
122 * if we get a null value.
123 */
124 if (key == null)
125 throw new NullPointerException("Null key in put(). value=" + value);
126 if (value == null)
127 throw new NullPointerException("Null value in put(). key=" + key);
128 try
129 {
130 /
131 * Wrapping object to Dbt type
132 */
133 ObjectDbt dbtKey = new ObjectDbt(key);
134 ObjectDbt dbtData = new ObjectDbt(value);
135 /
136 * Add to database, if key already exists, print out error message
137 */
138 int err;
139 if ((err = table.put(null, dbtKey, dbtData, 0)) == Db.DB_KEYEXIST)
140 {
141 System.out.println("BDBTest:" + dbtKey + " already exists.");
142 }
143 table.sync(0); // flushing all modified records from database cache to disk
144 }
145 catch (DbException dbe)
146 {
147 System.out.println(dbe.toString());
148 }
149 return value;
150 }//put();
151 /
152 * Gets the object associated with the specified key in the Storage object.
153 * @param key the specified object id
154 * @returns the element for the key, or null if the key
155 * is not defined in the Storage.
156 * @see Storage#put
157 */
158 public Object get(ObjectID key)
159 {
160 Dbc iterator;
161 Object obj1=null;
162 /
163 * Acquire an iterator for the table.
164 * Travel Storage to get elements for the specific key
165 * Decode a byte stream to XML
166 * and deserialize XML into the object to return.
167 */
168 try
169 {
170 iterator = table.cursor(null, 0);
171 ObjectDbt dbtKey = new ObjectDbt(key);
172 ObjectDbt dbtData = new ObjectDbt();
173 int err;
174 if ((err = iterator.get(dbtKey, dbtData, Db.DB_SET)) == Db.DB_NOTFOUND)
175 System.out.println("BDBTest" + dbtKey + " is not found.");
176 byte[] inbytesData = dbtData.get_data();
177 ByteArrayInputStream baisData = new ByteArrayInputStream(inbytesData);
178 ObjIn inData = new ObjIn(baisData); //using JSX API
179 iterator.close();
180 obj1 = inData.readObject();
181 }
182 catch (DbException dbe)
183 {
184 System.out.println(dbe.toString());
185 }
186 catch(IOException ioe)
187 {
188 System.out.println(ioe.toString());
189 }
190 catch(ClassNotFoundException cnfe)
191 {
192 System.out.println(cnfe.toString());
193 }
194 return obj1;
195 }//get();
196 /
197 * Returns the number of elements contained within the Storage object.
198 * Is an int big enough here?
199 */
200 public int size()
201 {
202 int numberOfKeys=0;
203 try
204 {
205 DbBtreeStat dbts = (DbBtreeStat)table.stat(Db.DB_FAST_STAT);
206 numberOfKeys = dbts.bt_nkeys;
207 }
208 catch (DbException dbe)
209 {
210 System.out.println(dbe.toString());
211 }
212 return numberOfKeys;
213 }//size();
214 /
215 * Returns true if the Storage object contains no elements.
216 */
217 public boolean isEmpty()
218 {
219 boolean bool=false;
220 if(size()== 0) bool= true;
221 return bool;
222 }//isEmpty();
223 /
224 * Removes the element corresponding to the key. Does nothing if the
225 * key is not present.
226 * @param key the key that needs to be removed
227 * @return the value of key, or null if the key was not found.
228 */
229 public Object remove(ObjectID key)
230 {
231 try
232 {
233 ObjectDbt dbtKey = new ObjectDbt(key);
234 table.del(null, dbtKey, 0);
235 }
236 catch (DbException dbe)
237 {
238 System.out.println(dbe.toString());
239 }
240 return null;
241 }//remove();
242 /
243 * Returns an enumeration of the Storage object's keys.
244 * Using similar approach for get() method.
245 * @see Storage#elements
246 * @see Storage#get
247 */
248 public Enumeration keys()
249 {
250 Dbc iterator;
251 Object obj1=null;
252 Vector ids=new Vector();
253 try
254 {
255 iterator = table.cursor(null, 0);
256 ObjectDbt dbtKey = new ObjectDbt();
257 ObjectDbt dbtData = new ObjectDbt();
258 while (iterator.get(dbtKey, dbtData, Db.DB_NEXT) == 0)
259 {
260 byte[] inbytes = dbtKey.get_data();
261 ByteArrayInputStream bais = new ByteArrayInputStream(inbytes);
262 ObjIn in = new ObjIn(bais);
263 Object key = in.readObject();
264 synchronized(ids) {
265 if (! ids.contains(key))
266 ids.addElement(key);
267 }
268 }//while
269 iterator.close();
270 }
271 catch (DbException dbe)
272 {
273 System.out.println(dbe.toString());
274 }
275 catch(IOException ioe)
276 {
277 System.out.println(ioe.toString());
278 }
279 catch(ClassNotFoundException cnfe)
280 {
281 System.out.println(cnfe.toString());
282 }
283 return ids.elements();
284 }//keys();
285 /
286 * Returns an enumeration of the elements.
287 * Using similar approach for get() method.
288 * @see Storage#keys
289 * @see Storage#get
290 */
291 public Enumeration elements()
292 {
293 Dbc iterator;
294 Object obj1=null;
295 Vector ids=new Vector();
296 try
297 {
298 iterator = table.cursor(null, 0);
299 ObjectDbt dbtKey = new ObjectDbt();
300 ObjectDbt dbtData = new ObjectDbt();
301 while (iterator.get(dbtKey, dbtData, Db.DB_NEXT) == 0)
302 {
303 byte[] inbytes = dbtData.get_data();
304 ByteArrayInputStream bais = new ByteArrayInputStream(inbytes);
305 ObjIn in = new ObjIn(bais);
306 Object data = in.readObject();
307 synchronized(ids) {
308 if (! ids.contains(data))
309 ids.addElement(data);
310 }
311 }//while
312 iterator.close();
313 }
314 catch (DbException dbe)
315 {
316 System.out.println(dbe.toString());
317 }
318 catch(IOException ioe)
319 {
320 System.out.println(ioe.toString());
321 }
322 catch(ClassNotFoundException cnfe)
323 {
324 System.out.println(cnfe.toString());
325 }
326 return ids.elements();
327 }//elements();
328 /
329 * Close database
330 */
331 public void dbclose()
332 throws DbException
333 {
334 try
335 {
336 table.close(0);
337 }
338 catch (DbException dbe)
339 {
340 System.out.println(dbe.toString());
341 }
342 }//dbclose()
343 }//BerkeleyDBStorageDemo
Back to Berkeley DB (Sleepycat) Storage
|