def syntaxQuote(self, form): from clojure.lang.compiler import builtins as compilerbuiltins if form in compilerbuiltins: ret = RT.list(_QUOTE_, form) elif isinstance(form, Symbol): sym = form if sym.ns is None and sym.name.endswith("#"): gmap = GENSYM_ENV.deref() if gmap == None: raise ReaderException("Gensym literal not in syntax-quote, before", self.rdr) gs = gmap[sym] if gs is None: gs = symbol(None, sym.name[:-1] + "__" + str(RT.nextID()) + "__auto__") GENSYM_ENV.set(gmap.assoc(sym, gs)) sym = gs elif sym.ns is None and sym.name.endswith("."): ret = sym elif sym.ns is None and sym.name.startswith("."): ret = sym elif sym.ns is not None: ret = sym else: comp = currentCompiler.get(lambda: None) if comp is None: raise IllegalStateException("No Compiler found in syntax quote!") ns = comp.getNS() if ns is None: raise IllegalStateException("No ns in reader") sym = symbol(ns.__name__, sym.name) ret = RT.list(_QUOTE_, sym) else: if isUnquote(form): return form.next().first() elif isUnquoteSplicing(form): raise IllegalStateException("splice not in list") elif isinstance(form, IPersistentCollection): if isinstance(form, IPersistentMap): keyvals = self.flattenMap(form) ret = RT.list(_APPLY_, _HASHMAP_, RT.list(RT.cons(_CONCAT_, self.sqExpandList(keyvals.seq())))) elif isinstance(form, (IPersistentVector, IPersistentSet)): ret = RT.list(_APPLY_, _VECTOR_, RT.list(_SEQ_, RT.cons(_CONCAT_, self.sqExpandList(form.seq())))) elif isinstance(form, (ISeq, IPersistentList)): seq = form.seq() if seq is None: ret = RT.cons(_LIST_, None) else: ret = RT.list(_SEQ_, RT.cons(_CONCAT_, self.sqExpandList(seq))) else: raise IllegalStateException("Unknown collection type") elif isinstance(form, (int, float, str, Keyword)): ret = form else: ret = RT.list(_QUOTE_, form) if hasattr(form, "meta") and form.meta() is not None: newMeta = form.meta().without(LINE_KEY) if len(newMeta) > 0: return RT.list(_WITH_META_, ret, self.syntaxQuote(form.meta()))#FIXME: _WITH_META_ undefined return ret
def handle_commutes(self, locks): for ref, funcpairs in self._commutes.items(): # If this ref has been ref-set or alter'ed before the commute, no need to re-apply # since we can be sure that the commute happened on the latest value of the ref if ref in self._sets: continue wasEnsured = ref in self._ensures self._releaseIfEnsured(ref) # Try to get a write lock---if some other transaction is # committing to this ref right now, retry this transaction self._tryWriteLock(ref) locks.append(ref) if wasEnsured and ref._tvals and ref._tvals.point > self._readPoint: self._retry("RETRY - was ensured and has newer version while commiting") other_refinfo = ref._tinfo if other_refinfo and other_refinfo != self._info and other_refinfo.running(): # Other transaction is currently running, and owns # this ref---meaning it set the ref's # in-transaction-value already, so we either barge # them or retry if not self._barge(other_refinfo): self._retry("RETRY - conflicting commutes being commited and barge failed") # Ok, no conflicting ref-set or alters to this ref, we can # make the change Update the val with the latest # in-transaction-version val = ref._tvals.val if ref._tvals else None self._vals[ref] = val # Now apply each commute to the latest value for fn, args in funcpairs: self._vals[ref] = fn(*RT.cons(self._vals[ref], args))
def seqFrom(self, key, ascending): if self._count > 0: stack = None t = self.tree while t is not None: c = self.doCompare(key, t.key()) if c == 0: stack = RT.cons(t, stack) return Seq(stack, ascending) elif ascending: if c < 0: stack = RT.cons(t, stack) t = t.left() else: t = t.right() else: if c > 0: stack = RT.cons(t, stack) t = t.right() else: t = t.left() if stack is not None: return Seq(stack, ascending) return None
def doCommute(self, ref, fn, args): """ Sets the in-transaction-value of this ref to the given value, but does not require other transactions that also change this ref to retry. Commutes are re-computed at commit time and apply on top of any more recent changes. """ if not self._info or not self._info.running(): self._retry("RETRY - Not running in doCommute!") # If we don't have an in-transaction-value yet for this ref # get the latest one if not ref in self._vals: with shared_lock(ref._lock): val = ref._tvals.val if ref._tvals else None self._vals[ref] = val # Add this commute function to the end of the list of commutes for this ref self._commutes.setdefault(ref, []).append([fn, args]) # Save the value we get by applying the fn now to our in-transaction-list returnValue = fn(*RT.cons(self._vals[ref], args)) self._vals[ref] = returnValue return returnValue
def pushRecur(self, label): """ Pushes a new recursion label. All recur calls will loop back to this point """ self.recurPoint = RT.cons(label, self.recurPoint)
def syntaxQuote(self, form): # compiler uses this module, so import it lazily from clojure.lang.compiler import builtins as compilerbuiltins if form in compilerbuiltins: ret = RT.list(_QUOTE_, form) elif isinstance(form, Symbol): sym = form if sym.ns is None and sym.name.endswith("#"): gmap = GENSYM_ENV.deref() if gmap == None: raise ReaderException("Gensym literal not in syntax-quote, before", self.rdr) gs = gmap[sym] if gs is None: gs = Symbol(None, "{0}__{1}__auto__".format(sym.name[:-1], RT.nextID())) GENSYM_ENV.set(gmap.assoc(sym, gs)) sym = gs elif sym.ns is None and sym.name.endswith("."): ret = sym elif sym.ns is None and sym.name.startswith("."): ret = sym elif sym.ns is not None: ret = sym else: comp = currentCompiler.deref() if comp is None: raise IllegalStateException("No Compiler found in syntax quote!") ns = comp.getNS() if ns is None: raise IllegalStateException("No ns in reader") item = namespace.findItem(ns, sym) if item is None: sym = Symbol(ns.__name__, sym.name) else: sym = Symbol(item.ns.__name__, sym.name) ret = RT.list(_QUOTE_, sym) else: if isUnquote(form): return form.next().first() elif isUnquoteSplicing(form): raise IllegalStateException("splice not in list") elif isinstance(form, IPersistentCollection): if isinstance(form, IPersistentMap): keyvals = self.flattenMap(form) ret = RT.list(_APPLY_, _HASHMAP_, RT.list(RT.cons(_CONCAT_, self.sqExpandList(keyvals.seq())))) elif isinstance(form, (IPersistentVector, IPersistentSet)): ret = RT.list(_APPLY_, _VECTOR_, RT.list(_SEQ_, RT.cons(_CONCAT_, self.sqExpandList(form.seq())))) elif isinstance(form, (ISeq, IPersistentList)): seq = form.seq() if seq is None: ret = RT.cons(_LIST_, None) else: ret = RT.list(_SEQ_, RT.cons(_CONCAT_, self.sqExpandList(seq))) else: raise IllegalStateException("Unknown collection type") elif isinstance(form, (int, float, str, Keyword)): ret = form else: ret = RT.list(_QUOTE_, form) if getattr(form, "meta", lambda: None)() is not None: newMeta = form.meta().without(LINE_KEY) if len(newMeta) > 0: return RT.list(_WITH_META_, ret, self.syntaxQuote(form.meta()))#FIXME: _WITH_META_ undefined return ret
def alter(self, fn, args): "Alters the value of this ref, and returns the new state" current = LockingTransaction.ensureGet().getRef(self) return self.refSet(fn(*RT.cons(current, args)))
def pushSeq(t, stack, asc): while t is not None: stack = RT.cons(t, stack) t = t.left() if asc else t.right() return stack