1 package org.apache.ojb.odmg.locking; 2 3 17 18 import org.apache.ojb.broker.Identity; 19 import org.apache.ojb.broker.PersistenceBroker; 20 import org.apache.ojb.broker.util.configuration.Configuration; 21 import org.apache.ojb.broker.util.configuration.ConfigurationException; 22 import org.apache.ojb.odmg.TransactionImpl; 23 import org.apache.ojb.odmg.TxManagerFactory; 24 25 import java.util.Collection ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.Map ; 29 import java.util.Vector ; 30 31 45 public class InMemoryLockMapImpl implements LockMap 46 { 47 52 private HashMap locktable = new HashMap (); 53 54 private long m_lastCleanupAt = System.currentTimeMillis(); 55 private static long CLEANUP_FREQUENCY = 500; private static int MAX_LOCKS_TO_CLEAN = 50; 57 58 62 public LockEntry getWriter(Object obj) 63 { 64 PersistenceBroker broker = getBroker(); 65 Identity oid = new Identity(obj, broker); 66 return getWriter(oid); 67 } 68 69 public LockEntry getWriter(Identity oid) 70 { 71 checkTimedOutLocks(); 72 73 ObjectLocks objectLocks = null; 78 synchronized(locktable) 79 { 80 objectLocks = (ObjectLocks) locktable.get(oid.toString()); 81 } 82 if (objectLocks == null) 83 { 84 return null; 85 } 86 else 87 { 88 return objectLocks.getWriter(); 89 } 90 } 91 92 95 private PersistenceBroker getBroker() 96 { 97 return TxManagerFactory.instance().getCurrentTransaction().getBroker(); 98 } 99 100 104 public Collection getReaders(Object obj) 105 { 106 checkTimedOutLocks(); 107 Identity oid = new Identity(obj,getBroker()); 108 return getReaders(oid); 109 } 110 111 public Collection getReaders(Identity oid) 112 { 113 ObjectLocks objectLocks = null; 114 synchronized (locktable) 115 { 116 objectLocks = (ObjectLocks) locktable.get(oid.toString()); 117 } 118 if (objectLocks == null) 119 { 120 return new Vector (); 121 } 122 else 123 { 124 return objectLocks.getReaders().values(); 125 } 126 } 127 128 132 public boolean addReader(TransactionImpl tx, Object obj) 133 { 134 checkTimedOutLocks(); 135 136 Identity oid = new Identity(obj,getBroker()); 137 LockEntry reader = new LockEntry(oid.toString(), 138 tx.getGUID(), 139 System.currentTimeMillis(), 140 LockStrategyFactory.getIsolationLevel(obj), 141 LockEntry.LOCK_READ); 142 143 addReaderInternal(reader); 144 return true; 145 } 146 147 void addReaderInternal(LockEntry reader) 148 { 149 ObjectLocks objectLocks = null; 150 154 synchronized (locktable) 155 { 156 String oidString = reader.getOidString(); 157 objectLocks = (ObjectLocks) locktable.get(oidString); 158 if (objectLocks == null) 159 { 160 objectLocks = new ObjectLocks(); 161 locktable.put(oidString, objectLocks); 162 } 163 } 164 objectLocks.addReader(reader); 165 } 166 167 171 public void removeReader(TransactionImpl tx, Object obj) 172 { 173 checkTimedOutLocks(); 174 175 Identity oid = new Identity(obj, getBroker()); 176 String oidString = oid.toString(); 177 String txGuid = tx.getGUID(); 178 removeReaderInternal(oidString, txGuid); 179 } 180 181 private void removeReaderInternal(String oidString, String txGuid) 182 { 183 ObjectLocks objectLocks = null; 184 synchronized (locktable) 185 { 186 objectLocks = (ObjectLocks) locktable.get(oidString); 187 } 188 if (objectLocks == null) 189 { 190 return; 191 } 192 else 193 { 194 199 synchronized (locktable) 200 { 201 Map readers = objectLocks.getReaders(); 202 readers.remove(txGuid); 203 if ((objectLocks.getWriter() == null) && (readers.size() == 0)) 204 { 205 locktable.remove(oidString); 206 } 207 } 208 } 209 } 210 211 void removeReaderByLock(LockEntry lock) 212 { 213 String oidString = lock.getOidString(); 214 String txGuid = lock.getTransactionId(); 215 removeReaderInternal(oidString, txGuid); 216 } 217 218 222 public void removeWriter(LockEntry writer) 223 { 224 checkTimedOutLocks(); 225 226 String oidString = writer.getOidString(); 227 ObjectLocks objectLocks = null; 228 synchronized (locktable) 229 { 230 objectLocks = (ObjectLocks) locktable.get(oidString); 231 } 232 if (objectLocks == null) 233 { 234 return; 235 } 236 else 237 { 238 243 synchronized (locktable) 244 { 245 Map readers = objectLocks.getReaders(); 246 objectLocks.setWriter(null); 247 if (readers.size() == 0) 249 { 250 locktable.remove(oidString); 251 } 252 } 253 } 254 } 255 256 260 public boolean upgradeLock(LockEntry reader) 261 { 262 checkTimedOutLocks(); 263 264 String oidString = reader.getOidString(); 265 ObjectLocks objectLocks = null; 266 synchronized (locktable) 267 { 268 objectLocks = (ObjectLocks) locktable.get(oidString); 269 } 270 271 if (objectLocks == null) 272 { 273 return false; 274 } 275 else 276 { 277 LockEntry writer = new LockEntry(reader.getOidString(), 279 reader.getTransactionId(), 280 System.currentTimeMillis(), 281 reader.getIsolationLevel(), 282 LockEntry.LOCK_WRITE); 283 objectLocks.setWriter(writer); 284 objectLocks.getReaders().remove(reader.getTransactionId()); 286 return true; 287 } 288 } 289 290 294 public boolean setWriter(TransactionImpl tx, Object obj) 295 { 296 checkTimedOutLocks(); 297 298 Identity oid = new Identity(obj, tx.getBroker()); 299 LockEntry writer = new LockEntry(oid.toString(), 300 tx.getGUID(), 301 System.currentTimeMillis(), 302 LockStrategyFactory.getIsolationLevel(obj), 303 LockEntry.LOCK_WRITE); 304 String oidString = oid.toString(); 305 setWriterInternal(writer, oidString); 306 return true; 307 } 308 309 private void setWriterInternal(LockEntry writer, String oidString) 310 { 311 ObjectLocks objectLocks = null; 312 316 synchronized (locktable) 317 { 318 objectLocks = (ObjectLocks) locktable.get(oidString); 319 if (objectLocks == null) 320 { 321 objectLocks = new ObjectLocks(); 322 locktable.put(oidString, objectLocks); 323 } 324 } 325 objectLocks.setWriter(writer); 326 } 327 328 void setWriterByLock(LockEntry writer) 329 { 330 String oidString = writer.getOidString(); 331 setWriterInternal(writer, oidString); 332 } 333 334 338 public boolean hasReadLock(TransactionImpl tx, Object obj) 339 { 340 checkTimedOutLocks(); 341 342 Identity oid = new Identity(obj,getBroker()); 343 String oidString = oid.toString(); 344 String txGuid = tx.getGUID(); 345 return hasReadLockInternal(oidString, txGuid); 346 } 347 348 private boolean hasReadLockInternal(String oidString, String txGuid) 349 { 350 ObjectLocks objectLocks = null; 351 synchronized (locktable) 352 { 353 objectLocks = (ObjectLocks) locktable.get(oidString); 354 } 355 356 if (objectLocks == null) 357 { 358 return false; 359 } 360 else 361 { 362 363 LockEntry reader = objectLocks.getReader(txGuid); 364 if (reader != null) 365 { 366 return true; 367 } 368 else 369 { 370 return false; 371 } 372 } 373 } 374 375 boolean hasReadLock(LockEntry entry) 376 { 377 String oidString = entry.getOidString(); 378 String txGuid = entry.getTransactionId(); 379 return hasReadLockInternal(oidString,txGuid); 380 } 381 382 private void checkTimedOutLocks() 383 { 384 if (System.currentTimeMillis() - m_lastCleanupAt > CLEANUP_FREQUENCY) 385 { 386 removeTimedOutLocks(AbstractLockStrategy.DEFAULT_LOCK_TIMEOUT); 387 m_lastCleanupAt = System.currentTimeMillis(); 388 } 389 } 390 391 395 private void removeTimedOutLocks(long timeout) 396 { 397 int count = 0; 398 long maxAge = System.currentTimeMillis() - timeout; 399 boolean breakFromLoop = false; 400 ObjectLocks temp = null; 401 synchronized (locktable) 402 { 403 Iterator it = locktable.values().iterator(); 404 410 while (it.hasNext() && !breakFromLoop && (count <= MAX_LOCKS_TO_CLEAN)) 411 { 412 temp = (ObjectLocks) it.next(); 413 if (temp.getWriter() != null) 414 { 415 if (temp.getWriter().getTimestamp() < maxAge) 416 { 417 temp.setWriter(null); 419 } 420 } 421 if (temp.getYoungestReader() < maxAge) 422 { 423 temp.getReaders().clear(); 425 if (temp.getWriter() == null) 426 { 427 it.remove(); 431 } 432 } 433 else 434 { 435 Iterator readerIt = temp.getReaders().values().iterator(); 437 LockEntry readerLock = null; 438 while (readerIt.hasNext()) 439 { 440 readerLock = (LockEntry) readerIt.next(); 441 if (readerLock.getTimestamp() < maxAge) 442 { 443 readerIt.remove(); 445 } 446 } 447 } 448 count++; 449 } 450 } 451 } 452 453 456 public void configure(Configuration pConfig) throws ConfigurationException 457 { 458 460 } 461 462 int getSize() 463 { 464 return locktable.size(); 465 } 466 467 } 468 | Popular Tags |