comparison src/org/dancres/blitz/oid/FIFOAllocatorImpl.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.oid;
2
3 import java.io.Serializable;
4 import java.io.IOException;
5
6 import java.util.Random;
7 import java.util.ArrayList;
8
9 import java.util.logging.*;
10
11 import org.dancres.blitz.disk.DiskTxn;
12 import org.dancres.blitz.disk.Disk;
13 import org.dancres.blitz.disk.Syncable;
14
15 import org.dancres.blitz.meta.Registry;
16 import org.dancres.blitz.meta.RegistryAccessor;
17 import org.dancres.blitz.meta.RegistryFactory;
18 import org.dancres.blitz.meta.MetaIterator;
19 import org.dancres.blitz.meta.MetaEntry;
20 import org.dancres.blitz.meta.Initializer;
21
22 import org.dancres.blitz.Logging;
23 import org.dancres.blitz.BootContext;
24
25 import org.dancres.blitz.txn.UnsyncdOps;
26
27 /**
28 <p>Provides an OID allocation service using a single zone at a time.
29 The early OID's are smaller numerically than later OID's such that the
30 user of these OID's can apply an ordering which yields FIFO behaviour.</p>
31 */
32 class FIFOAllocatorImpl implements AllocatorAdmin, Syncable {
33 static Logger theLogger =
34 Logging.newLogger("org.dancres.blitz.oid.Allocator");
35
36 private static final byte[] ALLOCATOR_KEY =
37 new byte[] {0x00, 0x00, 0x00, 0x01};
38
39 private static int MAX_ALLOCATOR = 512;
40
41 private OIDAllocator theAllocator;
42
43 private Registry theMetaData;
44 private String theName;
45
46 FIFOAllocatorImpl(String aName) throws IOException {
47 theLogger.log(Level.INFO, "FIFOAllocator: " + aName);
48
49 theMetaData =
50 RegistryFactory.get(getDbNameFor(aName),
51 new OIDInitializer());
52 theName = aName;
53
54 UnsyncdOps myBarrier = (UnsyncdOps)
55 BootContext.get(UnsyncdOps.class);
56
57 if (myBarrier != null) {
58 theLogger.log(Level.INFO, theName + ":Resync'ing allocator: " +
59 myBarrier.getOpsSinceLastCheckpoint());
60 }
61
62 loadAllocator();
63
64 if (myBarrier != null) {
65 theAllocator.jump(myBarrier.getOpsSinceLastCheckpoint());
66
67 if (theAllocator.isExhausted()) {
68 if (theAllocator.getId() == (MAX_ALLOCATOR - 1))
69 throw new Error("FIFOAllocator was exhausted - VERY BAD!");
70
71 theAllocator = new OIDAllocator(theAllocator.getId() + 1,
72 theAllocator.getId() + 1);
73 theAllocator.jump(myBarrier.getOpsSinceLastCheckpoint());
74 }
75
76 try {
77 sync();
78 } catch (Exception anE) {
79 theLogger.log(Level.SEVERE, theName +
80 ":Failed to sync against barrier",
81 anE);
82 throw new IOException("Failed to sync against barrier");
83 }
84 }
85
86 Disk.add(this);
87 }
88
89 private void loadAllocator() throws IOException {
90 DiskTxn myStandalone = DiskTxn.newStandalone();
91
92 MetaIterator myAllocatorStates =
93 theMetaData.getAccessor(myStandalone).readAll();
94
95 Serializable myEntry =
96 theMetaData.getAccessor(myStandalone).load(ALLOCATOR_KEY);
97
98 OIDAllocator myAllocator = new OIDAllocator();
99 myAllocator.setState(myEntry);
100
101 theAllocator = myAllocator;
102 myStandalone.commit();
103 }
104
105 /**
106 Call this within an active DiskTxn
107 */
108 public OID getNextId() throws IOException {
109 synchronized(this) {
110
111 OID myID = null;
112
113 if (theAllocator.isExhausted()) {
114 if (theAllocator.getId() == (MAX_ALLOCATOR - 1))
115 throw new Error("FIFOAllocator was exhausted - VERY BAD!");
116
117 theAllocator = new OIDAllocator(theAllocator.getId() + 1,
118 theAllocator.getId() + 1);
119 }
120
121 myID = theAllocator.newOID();
122
123 return myID;
124 }
125 }
126
127 public int getMaxZoneId() {
128 /*
129 HACK: We put up an arbitary limit, if we ever exceed this
130 we'll break LeaseTrackerImpl in blitz.entry
131 */
132 return MAX_ALLOCATOR;
133 }
134
135 public void sync() throws Exception {
136 DiskTxn myTxn = DiskTxn.newStandalone();
137
138 RegistryAccessor myAccessor = theMetaData.getAccessor(myTxn);
139
140 synchronized(this) {
141 myAccessor.save(ALLOCATOR_KEY, theAllocator.getState());
142 }
143
144 myTxn.commit(true);
145 }
146
147 public void close() throws Exception {
148 theMetaData.close();
149 }
150
151 public void delete() throws IOException {
152 theMetaData.close();
153
154 RegistryFactory.delete(getDbNameFor(theName));
155
156 Disk.remove(this);
157 }
158
159 private String getDbNameFor(String aName) {
160 return aName + "_oid";
161 }
162
163 private class OIDInitializer implements Initializer {
164 OIDInitializer() {
165 }
166
167 public void execute(RegistryAccessor anAccessor) throws IOException {
168 OIDAllocator myAlloc = new OIDAllocator(0);
169 anAccessor.save(ALLOCATOR_KEY, myAlloc.getState());
170 }
171 }
172 }