Mercurial > hg > blitz_condensed
diff src/org/dancres/blitz/ExistsFactory.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/dancres/blitz/ExistsFactory.java Sat Mar 21 11:00:06 2009 +0000 @@ -0,0 +1,110 @@ +package org.dancres.blitz; + +import java.lang.ref.WeakReference; +import java.io.IOException; + +import org.dancres.blitz.txnlock.BaulkedParty; +import org.dancres.blitz.entry.SearchVisitor; +import org.dancres.blitz.entry.EntryRepository; +import org.dancres.blitz.entry.EntryRepositoryFactory; +import org.dancres.blitz.mangler.MangledEntry; + +/** + * Use this class for *Exists searches return single results, bulk operations + * are <b>not</b> currently supported. + * + * This class maintains a count of transaction conflicts that have occurred + * and when it reaches zero, signals the associated <code>MatchTask</code> via + * it's <code>SearchVisitor</code>. Note the signal is only permitted after + * <code>enableResolutionSignal</code> has been called. This provides a + * barrier such that a full disk-search can be completed without false + * terminations from resulting conflicts. + */ +public class ExistsFactory implements VisitorBaulkedPartyFactory { + private int _conflicts; + private boolean _resolvable = false; + private WeakReference _task; + + public BaulkedParty newParty(SingleMatchTask aMatchTask) { + _task = new WeakReference(aMatchTask); + return new BaulkedPartyImpl(); + } + + public BaulkedParty newParty(BulkTakeVisitor aMatchTask) { + throw new RuntimeException + ("Exists not currently supported on bulk operations"); + } + + public void enableResolutionSignal() { + synchronized (this) { + _resolvable = true; + } + + testAndSignal(); + } + + private SearchVisitor getVisitor() { + MatchTask myTask = (MatchTask) _task.get(); + + if (myTask == null) + return null; + else + return myTask.getVisitor(); + } + + private void testAndSignal() { + int myConflicts; + + synchronized(this) { + if (!_resolvable) + return; + + myConflicts = _conflicts; + } + + if (myConflicts == 0) { + SingleMatchTask myTask = (SingleMatchTask) _task.get(); + + if (myTask != null) { + myTask.sendEvent(CompletionEvent.COMPLETED); + } + } + } + + private class BaulkedPartyImpl implements BaulkedParty { + + public BaulkedPartyImpl() { + } + + public void blocked(Object aHandback) { + synchronized(ExistsFactory.this) { + ++_conflicts; + } + } + + public void unblocked(Object aHandback) { + Handback myHandback = (Handback) aHandback; + + try { + SearchVisitor myVisitor = getVisitor(); + + if (myVisitor == null) + return; + + EntryRepository myRepos = + EntryRepositoryFactory.get().get(myHandback.getType()); + + myRepos.find(myVisitor, myHandback.getOID(), + myHandback.getEntry()); + + } catch (IOException aDbe) { + } finally { + synchronized(ExistsFactory.this) { + --_conflicts; + } + + testAndSignal(); + } + } + } +}