Mercurial > hg > blitz_condensed
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 } |