comparison src/org/dancres/blitz/entry/PersistentEntry.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 package org.dancres.blitz.entry;
2
3 import java.util.logging.Level;
4
5 import org.dancres.blitz.mangler.MangledEntry;
6 import org.dancres.blitz.oid.OIDFactory;
7 import org.dancres.blitz.oid.OID;
8 import org.dancres.util.ObjectTransformer;
9 import org.dancres.util.BytePacker;
10
11 /**
12 */
13 public class PersistentEntry {
14 private static final int EXPIRY_LENGTH = 8;
15
16 private static final int HASH_COUNT_LENGTH = 4;
17
18 /*
19 All disk-structures are kept "simple" - this removes the need for
20 costly (in terms of time to do it and space on disk) serialization
21 */
22 private byte[] theEntryBytes;
23 private long theExpiry;
24 private byte[] theKey;
25 private byte[] theHashCodes;
26
27 private transient MangledEntry theEntry;
28 private transient OID theId;
29
30 PersistentEntry(OID anId, MangledEntry anEntry, long anExpiry) {
31 theEntry = anEntry;
32 theId = anId;
33 theExpiry = anExpiry;
34 }
35
36 PersistentEntry(byte[] aBytes) {
37 BytePacker myPacker = BytePacker.getMSBPacker(aBytes);
38
39 theExpiry = myPacker.getLong(0);
40 theKey = myPacker.getArray(EXPIRY_LENGTH, OIDFactory.KEY_SIZE);
41
42 int myHashCodesLength =
43 myPacker.getInt(EXPIRY_LENGTH + OIDFactory.KEY_SIZE);
44
45 theHashCodes = myPacker.getArray(EXPIRY_LENGTH + OIDFactory.KEY_SIZE +
46 HASH_COUNT_LENGTH, myHashCodesLength);
47
48 int myRemainder = aBytes.length - EXPIRY_LENGTH - OIDFactory.KEY_SIZE -
49 myHashCodesLength - HASH_COUNT_LENGTH;
50
51 theEntryBytes = myPacker.getArray(EXPIRY_LENGTH + OIDFactory.KEY_SIZE +
52 myHashCodesLength +
53 HASH_COUNT_LENGTH,
54 myRemainder);
55 }
56
57 /**
58 * Convert EntrySleeveImpl into a byte representation suitable for
59 * saving to disk.
60 */
61 byte[] flatten() {
62 if (theEntryBytes == null) {
63 try {
64 theEntryBytes = ObjectTransformer.toByte(theEntry);
65 } catch (Exception anE) {
66 EntrySleeveImpl.theLogger.log(
67 Level.SEVERE, "Couldn't flatten entry!", anE);
68 }
69 }
70
71 byte[] myArray = new byte[theEntryBytes.length + OIDFactory.KEY_SIZE
72 + EXPIRY_LENGTH + HASH_COUNT_LENGTH +
73 getHashCodes().length];
74
75 BytePacker myPacker = BytePacker.getMSBPacker(myArray);
76 myPacker.putLong(theExpiry, 0);
77 myPacker.putArray(getKey(), EXPIRY_LENGTH);
78 myPacker.putInt(getHashCodes().length, EXPIRY_LENGTH +
79 OIDFactory.KEY_SIZE);
80 myPacker.putArray(getHashCodes(), EXPIRY_LENGTH + OIDFactory.KEY_SIZE +
81 HASH_COUNT_LENGTH);
82 myPacker.putArray(theEntryBytes, EXPIRY_LENGTH + OIDFactory.KEY_SIZE +
83 HASH_COUNT_LENGTH + getHashCodes().length);
84
85 return myArray;
86 }
87
88 PersistentEntry duplicate() {
89 return new PersistentEntry(getOID(), getEntry(), getExpiry());
90 }
91
92 private synchronized byte[] getHashCodes() {
93 /*
94 Should only happen if we've been newly created and never been
95 flattened
96 */
97 if (theHashCodes == null) {
98 MangledEntry myEntry = getEntry();
99
100 theHashCodes = new byte[myEntry.getFields().length * 4];
101
102 BytePacker myPacker = BytePacker.getMSBPacker(theHashCodes);
103
104 for (int i = 0; i < myEntry.getFields().length; i++) {
105 myPacker.putInt(myEntry.getField(i).hashCode(), i * 4);
106 }
107 }
108
109 return theHashCodes;
110 }
111
112 synchronized int getHashCodeForField(int anOffset) {
113 BytePacker myPacker = BytePacker.getMSBPacker(getHashCodes());
114
115 return myPacker.getInt(anOffset * 4);
116 }
117
118 synchronized MangledEntry getEntry() {
119 if (theEntry == null) {
120 try {
121 theEntry =
122 (MangledEntry) ObjectTransformer.toObject(theEntryBytes);
123 } catch (Exception anE) {
124 EntrySleeveImpl.theLogger.log(
125 Level.SEVERE, "Couldn't recover entry", anE);
126 }
127 }
128
129 return theEntry;
130 }
131
132 synchronized byte[] getKey() {
133
134 /*
135 Should only happen if we've been newly created and never been
136 flattened
137 */
138 if (theKey == null)
139 theKey = OIDFactory.getKey(theId);
140
141 return theKey;
142 }
143
144 synchronized OID getOID() {
145 if (theId == null) {
146 theId = OIDFactory.newOID(theKey);
147 }
148
149 return theId;
150 }
151
152 synchronized boolean hasExpired(long aTime) {
153 return (theExpiry < aTime);
154 }
155
156 synchronized void setExpiry(long anExpiry) {
157 theExpiry = anExpiry;
158 }
159
160 synchronized long getExpiry() {
161 return theExpiry;
162 }
163 }