diff --git a/TODO.FACTOR.txt b/TODO.FACTOR.txt index 17f3301681..74e574da68 100644 --- a/TODO.FACTOR.txt +++ b/TODO.FACTOR.txt @@ -4,7 +4,6 @@ - minimal use/in for parse-stream - prettyprint-1 - {...} vectors -- better .s - parsing should be parsing - telnetd: listening on a socket - vocab inspecting ==> worddef>list, assumes . on a list works diff --git a/factor/.FactorInterpreter.java.marks b/factor/.FactorInterpreter.java.marks index 58e4bbe58d..d7496649ac 100644 Binary files a/factor/.FactorInterpreter.java.marks and b/factor/.FactorInterpreter.java.marks differ diff --git a/factor/.FactorReader.java.marks b/factor/.FactorReader.java.marks index 9d2f99348b..de07f09e88 100644 --- a/factor/.FactorReader.java.marks +++ b/factor/.FactorReader.java.marks @@ -1 +1 @@ -!a;7528;7528 +!a;6964;6964 diff --git a/factor/.FactorShuffleDefinition.java.marks b/factor/.FactorShuffleDefinition.java.marks index e467daf6b7..a731dfa4dc 100644 Binary files a/factor/.FactorShuffleDefinition.java.marks and b/factor/.FactorShuffleDefinition.java.marks differ diff --git a/factor/.FactorWordDefinition.java.marks b/factor/.FactorWordDefinition.java.marks index 0fea901a82..99f9204906 100644 Binary files a/factor/.FactorWordDefinition.java.marks and b/factor/.FactorWordDefinition.java.marks differ diff --git a/factor/Cons.java b/factor/Cons.java index 342de068c1..54c0816333 100644 --- a/factor/Cons.java +++ b/factor/Cons.java @@ -160,39 +160,18 @@ public class Cons implements PublicCloneable, FactorExternalizable } } //}}} - //{{{ unparseDB() method - /** - * Returns elementsToDBString() enclosed with [ and ]. - */ - public String unparseDB() - { - return "[ " + elementsToString(true) + " ]"; - } //}}} - //{{{ elementsToString() method /** * Returns a whitespace separated string of the unparseObject() of each * item. */ public String elementsToString() - { - return elementsToString(false); - } //}}} - - //{{{ elementsToString() method - /** - * Returns a whitespace separated string of the unparseObject() of each - * item. - */ - public String elementsToString(boolean dbUnparse) { StringBuffer buf = new StringBuffer(); Cons iter = this; while(iter != null) { - buf.append(dbUnparse ? - FactorReader.unparseDBObject(iter.car) - : FactorReader.unparseObject(iter.car)); + buf.append(FactorReader.unparseObject(iter.car)); if(iter.cdr instanceof Cons) { buf.append(' '); @@ -204,9 +183,7 @@ public class Cons implements PublicCloneable, FactorExternalizable else { buf.append(" | "); - buf.append(dbUnparse ? - FactorReader.unparseDBObject(iter.cdr) - : FactorReader.unparseObject(iter.cdr)); + buf.append(FactorReader.unparseObject(iter.cdr)); iter = null; } } @@ -220,7 +197,7 @@ public class Cons implements PublicCloneable, FactorExternalizable */ public String toString() { - return "[ " + elementsToString(false) + " ]"; + return "[ " + elementsToString() + " ]"; } //}}} //{{{ toArray() method diff --git a/factor/FactorArray.java b/factor/FactorArray.java index 04258e5064..17fb2c22ac 100644 --- a/factor/FactorArray.java +++ b/factor/FactorArray.java @@ -30,10 +30,10 @@ package factor; /** - * Factor is a stack-based language. + * A growable array. * @author Slava Pestov */ -public class FactorArray implements PublicCloneable +public class FactorArray implements FactorExternalizable, PublicCloneable { public Object[] stack; public int top; @@ -159,6 +159,22 @@ public class FactorArray implements PublicCloneable return stack.length; } //}}} + //{{{ toString() method + /** + * Returns elementsToString() enclosed with [ and ]. + */ + public String toString() + { + StringBuffer buf = new StringBuffer("{ "); + for(int i = 0; i < top; i++) + { + buf.append(FactorReader.unparseObject(stack[i])); + buf.append(' '); + } + + return buf.append("}").toString(); + } //}}} + //{{{ toList() method public Cons toList() { diff --git a/factor/FactorCompoundDefinition.java b/factor/FactorCompoundDefinition.java index 23e827ae08..8cdaa39f44 100644 --- a/factor/FactorCompoundDefinition.java +++ b/factor/FactorCompoundDefinition.java @@ -30,8 +30,6 @@ package factor; import factor.compiler.*; -import factor.db.Workspace; -import factor.db.PersistenceException; import java.lang.reflect.*; import java.io.FileOutputStream; import java.util.*; @@ -52,29 +50,16 @@ public class FactorCompoundDefinition extends FactorWordDefinition * A new definition. */ public FactorCompoundDefinition(FactorWord word, Cons definition, - FactorInterpreter interp) throws PersistenceException + FactorInterpreter interp) { - super(word,interp.workspace); + super(word); fromList(definition,interp); - - if(interp.workspace != null) - interp.workspace.put(this); - } //}}} - - //{{{ FactorCompoundDefinition constructor - /** - * A blank definition, about to be unpickled. - */ - public FactorCompoundDefinition(Workspace workspace, long id) - { - super(workspace,id); } //}}} //{{{ eval() method public void eval(FactorInterpreter interp) throws Exception { - lazyInit(interp); interp.call(endOfDocs); } //}}} @@ -82,7 +67,6 @@ public class FactorCompoundDefinition extends FactorWordDefinition public void getStackEffect(RecursiveState recursiveCheck, FactorCompiler compiler) throws Exception { - lazyInit(compiler.interp); RecursiveForm rec = recursiveCheck.get(word); if(rec.active) { @@ -111,10 +95,8 @@ public class FactorCompoundDefinition extends FactorWordDefinition FactorWordDefinition compile(FactorInterpreter interp, RecursiveState recursiveCheck) throws Exception { - lazyInit(interp); // Each word has its own class loader - FactorClassLoader loader = new FactorClassLoader( - interp.workspace); + FactorClassLoader loader = new FactorClassLoader(); StackEffect effect = getStackEffect(interp); diff --git a/factor/FactorInterpreter.java b/factor/FactorInterpreter.java index 9e334ab986..2941bccc4c 100644 --- a/factor/FactorInterpreter.java +++ b/factor/FactorInterpreter.java @@ -29,20 +29,13 @@ package factor; -import factor.db.*; import factor.parser.*; import factor.primitives.*; import java.io.*; public class FactorInterpreter implements FactorObject, Runnable { - public static final String VERSION = "0.60.6"; - - // we need to call the 'boot' word from the init vocabulary. - private static final String INIT_VOCAB = "init"; - - // we need to call the 'throw' word from the errors vocabulary. - private static final String ERRORS_VOCAB = "errors"; + public static final String VERSION = "0.60.8"; // command line arguments are stored here. public Cons args; @@ -52,8 +45,9 @@ public class FactorInterpreter implements FactorObject, Runnable public Throwable error; public boolean dump = false; public boolean verboseCompile = false; - public boolean firstTime = false; public boolean mini = false; + // if this is false and an error occurs, bail out. + public boolean startupDone = false; public Cons callframe; public FactorArray callstack = new FactorArray(); @@ -87,11 +81,6 @@ public class FactorInterpreter implements FactorObject, Runnable */ public FactorWord last; - /** - * Persistent store, maybe null. - */ - public Workspace workspace; - public FactorNamespace global; private FactorNamespace interpNamespace; @@ -104,8 +93,6 @@ public class FactorInterpreter implements FactorObject, Runnable FactorInterpreter interp = new FactorInterpreter(); interp.init(args,null); interp.run(); - if(interp.workspace != null) - interp.workspace.close(); } //}}} //{{{ init() method @@ -115,7 +102,6 @@ public class FactorInterpreter implements FactorObject, Runnable this.interactive = interp.interactive; this.dump = interp.dump; this.verboseCompile = interp.verboseCompile; - this.firstTime = firstTime; this.callframe = interp.callframe; this.callstack = (FactorArray)interp.callstack.clone(); this.datastack = (FactorArray)interp.datastack.clone(); @@ -126,7 +112,6 @@ public class FactorInterpreter implements FactorObject, Runnable this.in = interp.in; this.builtins = interp.builtins; this.last = interp.last; - this.workspace = interp.workspace; this.global = interp.global; } //}}} @@ -136,39 +121,8 @@ public class FactorInterpreter implements FactorObject, Runnable for(int i = 0; i < args.length; i++) { String arg = args[i]; - if(arg.equals("-no-db")) - { - workspace = null; - args[i] = null; - } - else if(arg.equals("-db")) - { - if(workspace != null) - workspace.close(); - workspace = new Workspace( - new BTreeStore(new File("factor.db"), - (byte)64,false),false,this); - } - else if(arg.startsWith("-db:")) - { - if(workspace != null) - workspace.close(); - workspace = parseDBSpec(arg.substring(4)); - args[i] = null; - } - // this switch forces a first time init - else if(arg.equals("-no-first-time")) - { - firstTime = false; - args[i] = null; - } - else if(arg.equals("-first-time")) - { - firstTime = true; - args[i] = null; - } // this switch forces minimal libraries to be loaded - else if(arg.equals("-no-mini")) + if(arg.equals("-no-mini")) { mini = false; args[i] = null; @@ -182,7 +136,7 @@ public class FactorInterpreter implements FactorObject, Runnable this.args = Cons.fromArray(args); - vocabularies = new Table(workspace); + vocabularies = new FactorNamespace(); initBuiltinDictionary(); initNamespace(root); topLevel(); @@ -190,35 +144,10 @@ public class FactorInterpreter implements FactorObject, Runnable runBootstrap(); } //}}} - //{{{ parseDBSpec() method - private Workspace parseDBSpec(String db) throws Exception - { - int index = db.indexOf(':'); - String className = db.substring(0,index); - - String arg = db.substring(index + 1); - - boolean readOnly; - if(arg.startsWith("ro:")) - { - readOnly = true; - arg = arg.substring(3); - } - else - readOnly = false; - - Class[] consArgClasses = new Class[] { String.class }; - Object[] consArgs = new Object[] { arg }; - - return new Workspace((Store)Class.forName(className) - .getConstructor(consArgClasses) - .newInstance(consArgs),readOnly,this); - } //}}} - //{{{ initBuiltinDictionary() method private void initBuiltinDictionary() throws Exception { - builtins = new Table(null); + builtins = new FactorNamespace(); vocabularies.setVariable("builtins",builtins); in = "builtins"; @@ -226,129 +155,123 @@ public class FactorInterpreter implements FactorObject, Runnable // parsing words FactorWord lineComment = define("builtins","!"); - lineComment.parsing = new LineComment(lineComment,false,null); + lineComment.parsing = new LineComment(lineComment,false); FactorWord stackComment = define("builtins","("); - stackComment.parsing = new StackComment(stackComment,null); + stackComment.parsing = new StackComment(stackComment); FactorWord str = define("builtins","\""); - str.parsing = new StringLiteral(str,true,null); + str.parsing = new StringLiteral(str,true); FactorWord t = define("builtins","t"); - t.parsing = new T(t,null); + t.parsing = new T(t); FactorWord f = define("builtins","f"); - f.parsing = new F(f,null); + f.parsing = new F(f); FactorWord bra = define("builtins","["); - bra.parsing = new Bra(bra,null); + bra.parsing = new Bra(bra); FactorWord ket = define("builtins","]"); - ket.parsing = new Ket(bra,ket,null); + ket.parsing = new Ket(bra,ket); FactorWord bar = define("builtins","|"); - bar.parsing = new Bar(bar,null); + bar.parsing = new Bar(bar); FactorWord def = define("builtins",":"); - def.parsing = new Def(def,null); + def.parsing = new Def(def); def.getNamespace().setVariable("doc-comments",Boolean.TRUE); FactorWord ine = define("builtins",";"); - ine.parsing = new Ine(def,ine,null); + ine.parsing = new Ine(def,ine); FactorWord shuffle = define("builtins","~<<"); - shuffle.parsing = new Shuffle(shuffle,">>~",null); + shuffle.parsing = new Shuffle(shuffle,">>~"); FactorWord noParsing = define("builtins","POSTPONE:"); - noParsing.parsing = new NoParsing(noParsing,null); + noParsing.parsing = new NoParsing(noParsing); // #X FactorWord dispatch = define("builtins","#"); - dispatch.parsing = new Dispatch(dispatch,null); - FactorWord getPersistentObject = define("builtins","#O"); - getPersistentObject.parsing = new GetPersistentObject( - getPersistentObject,null); + dispatch.parsing = new Dispatch(dispatch); FactorWord ch = define("builtins","#\\"); - ch.parsing = new CharLiteral(ch,null); + ch.parsing = new CharLiteral(ch); FactorWord raw = define("builtins","#\""); - raw.parsing = new StringLiteral(raw,false,null); + raw.parsing = new StringLiteral(raw,false); FactorWord complex = define("builtins","#{"); - complex.parsing = new ComplexLiteral(complex,"}",null); + complex.parsing = new ComplexLiteral(complex,"}"); FactorWord docComment = define("builtins","#!"); - docComment.parsing = new LineComment(docComment,true,null); + docComment.parsing = new LineComment(docComment,true); FactorWord unreadable = define("builtins","#<"); - unreadable.parsing = new Unreadable(unreadable,null); + unreadable.parsing = new Unreadable(unreadable); // #: is not handled with a special dispatch. instead, when // a word starting with #: is passed to intern(), it creates // a new symbol FactorWord passthru = define("builtins","#:"); - passthru.parsing = new PassThrough(passthru,null); + passthru.parsing = new PassThrough(passthru); // vocabulary parsing words FactorWord defer = define("builtins","DEFER:"); - defer.parsing = new Defer(defer,null); + defer.parsing = new Defer(defer); FactorWord in = define("builtins","IN:"); - in.parsing = new In(in,null); + in.parsing = new In(in); FactorWord use = define("builtins","USE:"); - use.parsing = new Use(use,null); + use.parsing = new Use(use); FactorWord interpreterGet = define("builtins","interpreter"); - interpreterGet.def = new InterpreterGet(interpreterGet,null); + interpreterGet.def = new InterpreterGet(interpreterGet); interpreterGet.inline = true; // reading numbers with another base FactorWord bin = define("builtins","BIN:"); - bin.parsing = new Base(defer,null,2); + bin.parsing = new Base(bin,2); FactorWord oct = define("builtins","OCT:"); - oct.parsing = new Base(defer,null,8); + oct.parsing = new Base(oct,8); FactorWord hex = define("builtins","HEX:"); - hex.parsing = new Base(defer,null,16); + hex.parsing = new Base(hex,16); // primitives used by 'expand' and 'map' FactorWord restack = define("builtins","restack"); - restack.def = new Restack(restack,null); + restack.def = new Restack(restack); FactorWord unstack = define("builtins","unstack"); - unstack.def = new Unstack(unstack,null); + unstack.def = new Unstack(unstack); // reflection primitives FactorWord jinvoke = define("builtins","jinvoke"); - jinvoke.def = new JInvoke(jinvoke,null,false); + jinvoke.def = new JInvoke(jinvoke,false); jinvoke.inline = true; FactorWord jinvokeStatic = define("builtins","jinvoke-static"); - jinvokeStatic.def = new JInvoke(jinvokeStatic,null,true); + jinvokeStatic.def = new JInvoke(jinvokeStatic,true); jinvokeStatic.inline = true; FactorWord jnew = define("builtins","jnew"); - jnew.def = new JNew(jnew,null); + jnew.def = new JNew(jnew); jnew.inline = true; FactorWord jvarGet = define("builtins","jvar-get"); - jvarGet.def = new JVarGet(jvarGet,null); + jvarGet.def = new JVarGet(jvarGet); jvarGet.inline = true; FactorWord jvarGetStatic = define("builtins","jvar-static-get"); - jvarGetStatic.def = new JVarGetStatic(jvarGetStatic,null); + jvarGetStatic.def = new JVarGetStatic(jvarGetStatic); jvarGetStatic.inline = true; FactorWord jvarSet = define("builtins","jvar-set"); - jvarSet.def = new JVarSet(jvarSet,null); + jvarSet.def = new JVarSet(jvarSet); jvarSet.inline = true; FactorWord jvarSetStatic = define("builtins","jvar-static-set"); - jvarSetStatic.def = new JVarSetStatic(jvarSetStatic,null); + jvarSetStatic.def = new JVarSetStatic(jvarSetStatic); jvarSetStatic.inline = true; FactorWord coerce = define("builtins","coerce"); - coerce.def = new Coerce(coerce,null); + coerce.def = new Coerce(coerce); coerce.inline = true; // definition FactorWord define = define("builtins","define"); - define.def = new Define(define,null); + define.def = new Define(define); // combinators FactorWord execute = define("builtins","execute"); - execute.def = new Execute(execute,null); + execute.def = new Execute(execute); FactorWord call = define("builtins","call"); - call.def = new Call(call,null); + call.def = new Call(call); call.inline = true; FactorWord ifte = define("builtins","ifte"); - ifte.def = new Ifte(ifte,null); + ifte.def = new Ifte(ifte); ifte.inline = true; } //}}} //{{{ initNamespace() method private void initNamespace(Object root) throws Exception { - if(workspace == null) - global = new FactorNamespace(null,root); - else - global = workspace.getRoot(); + global = new FactorNamespace(null,root); global.setVariable("interpreter",this); @@ -357,37 +280,14 @@ public class FactorInterpreter implements FactorObject, Runnable getClass().getField("verboseCompile"), this)); - global.setVariable("global", + global.setVariable("startup-done", new FactorNamespace.VarBinding( - getClass().getField("global"), + getClass().getField("startupDone"), this)); - FactorNamespace newVocabs; - try - { - Object obj = global.getVariable("vocabularies"); - if(!(obj instanceof FactorNamespace)) - newVocabs = new Table(workspace); - else - newVocabs = (FactorNamespace)obj; - } - catch(Exception e) - { - System.err.println("Vocabularies table corrupt: " + e); - newVocabs = new Table(workspace); - } - - vocabularies = newVocabs; - - global.setVariable("vocabularies", - new FactorNamespace.VarBinding( - getClass().getField("vocabularies"), - this)); - - // Shouldn't have to do this twice! - initBuiltinDictionary(); - String[] boundFields = { + "global", + "vocabularies", "args", "dump", "interactive", @@ -420,24 +320,16 @@ public class FactorInterpreter implements FactorObject, Runnable //{{{ runBootstrap() method private void runBootstrap() throws Exception { - if(workspace == null || workspace.isFirstTime() - || firstTime) - { - if(workspace != null) - workspace.setFirstTime(false); - String initFile = "/library/platform/jvm/boot.factor"; - FactorReader parser = new FactorReader( - initFile, - new BufferedReader( - new InputStreamReader( - getClass().getResourceAsStream( - initFile))), - this); - - call(parser.parse()); - } - else - eval(searchVocabulary(INIT_VOCAB,"boot")); + String initFile = "/library/platform/jvm/boot.factor"; + FactorReader parser = new FactorReader( + initFile, + new BufferedReader( + new InputStreamReader( + getClass().getResourceAsStream( + initFile))), + this); + + call(parser.parse()); run(); } //}}} @@ -479,17 +371,27 @@ public class FactorInterpreter implements FactorObject, Runnable private boolean handleError(Throwable e) { error = FactorJava.unwrapException(e); + if(!startupDone) + { + error.printStackTrace(); + topLevel(); + return true; + } + datastack.push(error); try { - eval(searchVocabulary(ERRORS_VOCAB,"throw")); + FactorWord throwWord = searchVocabulary( + "errors","throw"); + if(throwWord == null) + throw new NullPointerException(); + eval(throwWord); return false; } catch(Throwable e2) { System.err.println("Exception when calling throw:"); e.printStackTrace(); - topLevel(); return true; @@ -609,7 +511,7 @@ public class FactorInterpreter implements FactorObject, Runnable Object value = vocabularies.getVariable(name); if(value == null) { - value = new Table(workspace); + value = new FactorNamespace(); vocabularies.setVariable(name,value); } } //}}} @@ -680,7 +582,7 @@ public class FactorInterpreter implements FactorObject, Runnable FactorNamespace v = getVocabulary(vocabulary); if(v == null) { - v = new Table(workspace); + v = new FactorNamespace(); vocabularies.setVariable(vocabulary,v); } Object value = v.getVariable(name); @@ -688,18 +590,9 @@ public class FactorInterpreter implements FactorObject, Runnable return (FactorWord)value; else { - Workspace workspace; - if(v instanceof PersistentObject) - { - workspace = ((PersistentObject)v) - .getWorkspace(); - } - else - workspace = null; - // save to same workspace as vocabulary, // or no workspace if vocabulary is builtins - FactorWord word = new FactorWord(workspace, + FactorWord word = new FactorWord( vocabulary,name,null); v.setVariable(name,word); return word; @@ -724,8 +617,11 @@ public class FactorInterpreter implements FactorObject, Runnable namestack.push(global); catchstack.top = 0; // DEFER: the word - define(ERRORS_VOCAB,"default-error-handler"); - catchstack.push(new Cons(searchVocabulary(ERRORS_VOCAB, + define("kernel","exit*"); + catchstack.push(new Cons(new Integer(1), + new Cons(searchVocabulary("kernel","exit*"),null))); + define("errors","default-error-handler"); + catchstack.push(new Cons(searchVocabulary("errors", "default-error-handler"),null)); callframe = null; } //}}} diff --git a/factor/FactorParsingDefinition.java b/factor/FactorParsingDefinition.java index 09f0a4a9cc..6652bbeb9c 100644 --- a/factor/FactorParsingDefinition.java +++ b/factor/FactorParsingDefinition.java @@ -29,13 +29,12 @@ package factor; -import factor.db.*; import java.io.IOException; /** * A parsing word definition. */ -public abstract class FactorParsingDefinition extends SimplePersistentObject +public abstract class FactorParsingDefinition { public static final String ENCODING = "UTF8"; @@ -45,24 +44,10 @@ public abstract class FactorParsingDefinition extends SimplePersistentObject /** * A new definition. */ - public FactorParsingDefinition(FactorWord word, Workspace workspace) + public FactorParsingDefinition(FactorWord word) throws Exception { - this(workspace,workspace == null - ? 0L : workspace.nextID()); this.word = word; - if(workspace != null && id != 0L) - workspace.put(this); - } //}}} - - //{{{ FactorParsingDefinition constructor - /** - * A blank definition, about to be unpickled. - */ - public FactorParsingDefinition(Workspace workspace, long id) - throws Exception - { - super(workspace,id); } //}}} public abstract void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/FactorPrimitiveDefinition.java b/factor/FactorPrimitiveDefinition.java index 65c78739fb..e4e2c95ab4 100644 --- a/factor/FactorPrimitiveDefinition.java +++ b/factor/FactorPrimitiveDefinition.java @@ -30,7 +30,6 @@ package factor; import factor.compiler.*; -import factor.db.*; import java.util.Set; /** @@ -42,22 +41,9 @@ public abstract class FactorPrimitiveDefinition extends FactorWordDefinition /** * A new definition. */ - public FactorPrimitiveDefinition(FactorWord word, Workspace workspace) - throws Exception + public FactorPrimitiveDefinition(FactorWord word) { - super(word,workspace); - if(workspace != null) - workspace.put(this); - } //}}} - - //{{{ FactorPrimitiveDefinition constructor - /** - * A blank definition, about to be unpickled. - */ - public FactorPrimitiveDefinition(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ fromList() method diff --git a/factor/FactorReader.java b/factor/FactorReader.java index ac33cfccff..c105c61d86 100644 --- a/factor/FactorReader.java +++ b/factor/FactorReader.java @@ -29,8 +29,6 @@ package factor; -import factor.db.PersistentIgnore; -import factor.db.PersistentObject; import java.io.*; import java.util.*; @@ -230,28 +228,6 @@ public class FactorReader } } //}}} - //{{{ unparseDBObject() method - public static String unparseDBObject(Object obj) - { - if(obj instanceof PersistentIgnore) - return "f"; - else if(obj instanceof PersistentObject) - { - PersistentObject pobj = (PersistentObject)obj; - if(pobj.getWorkspace() != null - && pobj.getID() != 0L) - { - return "#O" + pobj.getID(); - } - else - return unparseObject(obj); - } - else if(obj instanceof Cons) - return ((Cons)obj).unparseDB(); - else - return unparseObject(obj); - } //}}} - //{{{ unparseObject() method public static String unparseObject(Object obj) { diff --git a/factor/FactorShuffleDefinition.java b/factor/FactorShuffleDefinition.java index 99947ec029..ab62ac957b 100644 --- a/factor/FactorShuffleDefinition.java +++ b/factor/FactorShuffleDefinition.java @@ -30,7 +30,6 @@ package factor; import factor.compiler.*; -import factor.db.Workspace; import java.util.*; import org.objectweb.asm.*; @@ -59,21 +58,12 @@ public class FactorShuffleDefinition extends FactorWordDefinition private int shuffleRstart; private int shuffleRlength; - //{{{ FactorShuffleDefinition constructor - public FactorShuffleDefinition(Workspace workspace, long id) - { - super(workspace,id); - } //}}} - //{{{ FactorShuffleDefinition constructor public FactorShuffleDefinition(FactorWord word, Cons definition, FactorInterpreter interp) throws FactorException { - super(word,interp.workspace); + super(word); fromList(definition,interp); - - if(interp.workspace != null) - interp.workspace.put(this); } //}}} //{{{ FactorShuffleDefinition constructor @@ -162,8 +152,6 @@ public class FactorShuffleDefinition extends FactorWordDefinition FactorArray callstack) throws FactorStackException { - lazyInit(interp); - if(datastack.top < consumeD) throw new FactorStackException(consumeD); diff --git a/factor/FactorWord.java b/factor/FactorWord.java index 4ccafd04dd..470abd08f2 100644 --- a/factor/FactorWord.java +++ b/factor/FactorWord.java @@ -30,14 +30,12 @@ package factor; import factor.compiler.*; -import factor.db.*; import java.util.*; /** * An internalized symbol. */ -public class FactorWord extends SimplePersistentObject - implements FactorExternalizable +public class FactorWord implements FactorExternalizable, FactorObject { private static int gensymCount = 0; @@ -75,32 +73,20 @@ public class FactorWord extends SimplePersistentObject public FactorClassLoader loader; public String className; + private FactorNamespace namespace; + //{{{ FactorWord constructor /** * Do not use this constructor unless you're writing a packages * implementation or something. Use an FactorDictionary's * intern() method instead. */ - public FactorWord(Workspace workspace, long id) throws Exception - { - super(workspace,id); - } //}}} - - //{{{ FactorWord constructor - /** - * Do not use this constructor unless you're writing a packages - * implementation or something. Use an FactorDictionary's - * intern() method instead. - */ - public FactorWord(Workspace workspace, String vocabulary, String name, + public FactorWord(String vocabulary, String name, FactorWordDefinition def) throws Exception { - this(workspace,workspace == null ? 0L : workspace.nextID()); this.vocabulary = vocabulary; this.name = name; this.def = def; - if(workspace != null && id != 0L) - workspace.put(this); } //}}} //{{{ FactorWord constructor @@ -115,6 +101,15 @@ public class FactorWord extends SimplePersistentObject this.name = name; } //}}} + //{{{ getNamespace() method + public FactorNamespace getNamespace() + throws Exception + { + if(namespace == null) + namespace = new FactorNamespace(this); + return namespace; + } //}}} + //{{{ gensym() method /** * Returns an un-internalized word with a unique name. @@ -126,7 +121,6 @@ public class FactorWord extends SimplePersistentObject //{{{ define() method public synchronized void define(FactorWordDefinition def) - throws PersistenceException { if(compileRef) { @@ -140,20 +134,14 @@ public class FactorWord extends SimplePersistentObject loader = null; className = null; - - if(workspace != null && id != 0L) - workspace.put(this); } //}}} //{{{ setCompiledInfo() method synchronized void setCompiledInfo(FactorClassLoader loader, - String className) throws PersistenceException + String className) { this.loader = loader; this.className = className; - - if(workspace != null && id != 0L) - workspace.put(this); } //}}} //{{{ compile() method @@ -165,30 +153,6 @@ public class FactorWord extends SimplePersistentObject recursiveCheck.remove(this); } //}}} - //{{{ unpickle() method - /** - * Each persistent object can set its state to that in a byte array. - */ - public synchronized void unpickle(byte[] bytes, int offset, - FactorInterpreter interp) throws PersistenceException - { - super.unpickle(bytes,offset); - - if(loader != null && className != null) - { - try - { - def = CompiledDefinition.create(interp, - this,loader.loadClass(className)); - } - catch(Throwable e) - { - System.err.println("WARNING: cannot unpickle compiled definition"); - e.printStackTrace(); - } - } - } //}}} - //{{{ compile() method public synchronized void compile(FactorInterpreter interp, RecursiveState recursiveCheck) diff --git a/factor/FactorWordDefinition.java b/factor/FactorWordDefinition.java index 938b8ca808..d780eb596e 100644 --- a/factor/FactorWordDefinition.java +++ b/factor/FactorWordDefinition.java @@ -29,7 +29,6 @@ package factor; -import factor.db.*; import factor.compiler.*; import java.io.*; import java.util.*; @@ -37,21 +36,9 @@ import org.objectweb.asm.*; /** * A word definition. - * - * The pickled form is an unparsed list. The car of the list is the word, - * the cdr is toList(). */ -public abstract class FactorWordDefinition - implements Constants, PersistentObject +public abstract class FactorWordDefinition implements Constants { - public static final String ENCODING = "UTF8"; - - private String unparsed; - private boolean initialized; - - private Workspace workspace; - private long id; - protected FactorWord word; public boolean compileFailed; @@ -60,32 +47,9 @@ public abstract class FactorWordDefinition /** * A new definition. */ - public FactorWordDefinition(FactorWord word, Workspace workspace) - { - this(workspace,workspace == null - ? 0L : workspace.nextID()); - this.word = word; - initialized = true; - } //}}} - - //{{{ FactorWordDefinition constructor - /** - * A blank definition, about to be unpickled. - */ - public FactorWordDefinition(Workspace workspace, long id) - { - this.workspace = workspace; - this.id = id; - } //}}} - - //{{{ FactorWordDefinition constructor - /** - * A definition that is not saved in the current workspace. - */ public FactorWordDefinition(FactorWord word) { this.word = word; - initialized = true; } //}}} public abstract void eval(FactorInterpreter interp) @@ -94,15 +58,14 @@ public abstract class FactorWordDefinition //{{{ getWord() method public FactorWord getWord(FactorInterpreter interp) { - lazyInit(interp); return word; } //}}} //{{{ fromList() method public void fromList(Cons cons, FactorInterpreter interp) - throws FactorRuntimeException, PersistenceException + throws FactorRuntimeException { - throw new PersistenceException("Cannot unpickle " + this); + throw new FactorRuntimeException("Cannot unpickle " + this); } //}}} //{{{ toList() method @@ -123,7 +86,6 @@ public abstract class FactorWordDefinition FactorInterpreter interp) throws Exception { FactorCompiler compiler = new FactorCompiler(interp); - lazyInit(interp); recursiveCheck.add(word,new StackEffect(),null,null,null); getStackEffect(recursiveCheck,compiler); recursiveCheck.remove(word); @@ -134,7 +96,6 @@ public abstract class FactorWordDefinition public void getStackEffect(RecursiveState recursiveCheck, FactorCompiler compiler) throws Exception { - lazyInit(compiler.interp); throw new FactorCompilerException("Cannot deduce stack effect of " + word); } //}}} @@ -152,8 +113,6 @@ public abstract class FactorWordDefinition public void compileCallTo(CodeVisitor mw, FactorCompiler compiler, RecursiveState recursiveCheck) throws Exception { - lazyInit(compiler.interp); - // normal word String defclass; String defmethod; @@ -262,8 +221,6 @@ public abstract class FactorWordDefinition RecursiveState recursiveCheck, StackEffect immediateEffect) throws Exception { - lazyInit(compiler.interp); - Cons definition = toList(compiler.getInterpreter()); Cons endOfDocs = definition; @@ -372,98 +329,6 @@ public abstract class FactorWordDefinition } } //}}} - //{{{ getWorkspace() method - /** - * Each persistent object is stored in one workspace only. - */ - public Workspace getWorkspace() - { - return workspace; - } //}}} - - //{{{ getID() method - /** - * Each persistent object has an associated ID. - */ - public long getID() - { - return id; - } //}}} - - //{{{ lazyInit() method - public synchronized void lazyInit(FactorInterpreter interp) - { - if(initialized) - return; - - initialized = true; - - try - { - Cons pickle = (Cons)FactorReader.parseObject( - unparsed,interp); - word = (FactorWord)pickle.car; - //System.err.println(word + " unpickled"); - fromList(pickle.next(),interp); - } - catch(Exception e) - { - // should not happen with byte array stream - throw new RuntimeException("Unexpected error",e); - } - } //}}} - - //{{{ pickle() method - /** - * Each persistent object can turn itself into a byte array. - */ - public byte[] pickle() - throws PersistenceException - { - try - { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - - Cons pickle = new Cons(word,toList( - workspace.getInterpreter())); - bytes.write((FactorReader.getVocabularyDeclaration(pickle) - + FactorReader.unparseDBObject(pickle)) - .getBytes(ENCODING)); - - return bytes.toByteArray(); - } - catch(Exception e) - { - // should not happen with byte array stream - throw new PersistenceException("Unexpected error",e); - } - } //}}} - - //{{{ unpickle() method - /** - * Each persistent object can set its state to that in a byte array. - */ - public void unpickle(byte[] bytes, int offset) - throws PersistenceException - { - try - { - unparsed = new String(bytes,offset, - bytes.length - offset,ENCODING); - } - catch(Exception e) - { - // should not happen with byte array stream - throw new PersistenceException("Unexpected error",e); - } - } //}}} - - //{{{ getReferences() method - public Cons getReferences() - { - return toList(workspace.getInterpreter()); - } //}}} - //{{{ toString() method public String toString() { diff --git a/factor/compiler/CompiledDefinition.java b/factor/compiler/CompiledDefinition.java index dae97a911b..1bf9bd317b 100644 --- a/factor/compiler/CompiledDefinition.java +++ b/factor/compiler/CompiledDefinition.java @@ -39,7 +39,6 @@ import org.objectweb.asm.*; */ public abstract class CompiledDefinition extends FactorWordDefinition - implements factor.db.PersistentIgnore { //{{{ CompiledDefinition constructor public CompiledDefinition(FactorWord word) diff --git a/factor/compiler/FactorClassLoader.java b/factor/compiler/FactorClassLoader.java index 50df8e8a84..dc633e90e9 100644 --- a/factor/compiler/FactorClassLoader.java +++ b/factor/compiler/FactorClassLoader.java @@ -29,9 +29,7 @@ package factor.compiler; -import factor.Cons; -import factor.FactorInterpreter; -import factor.db.*; +import factor.*; import java.util.*; /** @@ -40,28 +38,10 @@ import java.util.*; * When compiling a word; add each dependent word to new class loader's * delegates map. */ -public class FactorClassLoader extends ClassLoader implements PersistentObject +public class FactorClassLoader extends ClassLoader { - private Workspace workspace; private long id; - private Table table; - - //{{{ FactorClassLoader constructor - public FactorClassLoader(Workspace workspace, long id) - throws Exception - { - this.workspace = workspace; - this.id = id; - table = new Table(null,workspace,0L); - if(workspace != null && id != 0L) - workspace.put(this); - } //}}} - - //{{{ FactorClassLoader constructor - public FactorClassLoader(Workspace workspace) throws Exception - { - this(workspace,workspace == null ? 0L : workspace.nextID()); - } //}}} + private FactorNamespace table = new FactorNamespace(); //{{{ addDependency() method public void addDependency(String name, FactorClassLoader loader) @@ -69,8 +49,6 @@ public class FactorClassLoader extends ClassLoader implements PersistentObject try { table.setVariable(name,loader); - if(workspace != null && id != 0L) - workspace.put(this); } catch(Exception e) { @@ -78,57 +56,9 @@ public class FactorClassLoader extends ClassLoader implements PersistentObject } } //}}} - //{{{ getWorkspace() method - /** - * Each persistent object is stored in one workspace only. - */ - public Workspace getWorkspace() - { - return workspace; - } //}}} - - //{{{ getID() method - /** - * Each persistent object has an associated ID. - */ - public long getID() - { - return id; - } //}}} - - //{{{ pickle() method - /** - * Each persistent object can turn itself into a byte array. - */ - public byte[] pickle() - throws PersistenceException - { - return table.pickle(); - } //}}} - - //{{{ unpickle() method - /** - * Each persistent object can set its state to that in a byte array. - */ - public void unpickle(byte[] bytes, int offset) - throws PersistenceException - { - table.unpickle(bytes,offset); - } //}}} - //{{{ addClass() method public Class addClass(String name, byte[] code, int off, int len) { - try - { - table.setVariable(name, - new PersistentBinary(workspace,code)); - } - catch(Exception e) - { - throw new RuntimeException(e); - } - return defineClass(name,code,off,len); } //}}} @@ -153,16 +83,6 @@ public class FactorClassLoader extends ClassLoader implements PersistentObject return ((FactorClassLoader)obj) .loadClass(name,resolve); } - else if(obj instanceof PersistentBinary) - { - byte[] bytes = ((PersistentBinary)obj) - .getBytes(); - c = defineClass( - name,bytes,0,bytes.length); - if(resolve) - resolveClass(c); - return c; - } else if(obj != null) { System.err.println("WARNING: unknown object in class loader table for " + this + ": " + obj); @@ -179,10 +99,4 @@ public class FactorClassLoader extends ClassLoader implements PersistentObject throw new RuntimeException(e); } } //}}} - - //{{{ getReferences() method - public Cons getReferences() - { - return table.getReferences(); - } //}}} } diff --git a/factor/db/BTreeException.java b/factor/db/BTreeException.java deleted file mode 100644 index 4465beb2c4..0000000000 --- a/factor/db/BTreeException.java +++ /dev/null @@ -1,48 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -public class BTreeException extends PersistenceException -{ - public BTreeException() - { - super(); - } - - public BTreeException(String msg) - { - super(msg); - } - - public BTreeException(String msg, Throwable t) - { - super(msg,t); - } -} diff --git a/factor/db/BTreeNode.java b/factor/db/BTreeNode.java deleted file mode 100644 index 305baff492..0000000000 --- a/factor/db/BTreeNode.java +++ /dev/null @@ -1,277 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import java.io.*; - -/** - * A B-tree index node. - * - * Format on disk is: - * - 1 byte: leaf flag for sanity check - * - 1 byte: num children - * - 8 * order bytes: keys - * - 8 * order bytes: pointers - */ -class BTreeNode -{ - // these two are not saved to disk. - byte order; - long offset; - - boolean leaf; - int children; - long[] keys; - - /** - * In the nodes a the bottom of the tree, these are pointers inside - * the data file; otherwise they are pointers inside the index file. - */ - long[] pointers; - - /** - * Set to true if the node changed and should be saved to disk. - */ - boolean dirty; - - //{{{ getSize() method - /** - * Returns the size in bytes of a node with the given order. - */ - public static int getSize(int order) - { - return 2 + order * 16; - } //}}} - - //{{{ BTreeNode constructor - BTreeNode(byte order, long offset) - { - this.order = order; - this.offset = offset; - this.keys = new long[order]; - this.pointers = new long[order]; - } //}}} - - //{{{ unpackLong() method - private long unpackLong(byte[] data, int offset) - { - return (((long)data[offset + 0] << 56) + - ((long)(data[offset + 1] & 255) << 48) + - ((long)(data[offset + 2] & 255) << 40) + - ((long)(data[offset + 3] & 255) << 32) + - ((long)(data[offset + 4] & 255) << 24) + - ((data[offset + 5] & 255) << 16) + - ((data[offset + 6] & 255) << 8) + - ((data[offset + 7] & 255) << 0)); - } //}}} - - //{{{ read() method - void read(RandomAccessFile in) throws IOException - { - in.seek(offset); - - byte[] data = new byte[getSize(order)]; - in.readFully(data); - - int pos = 0; - leaf = (data[pos++] != 0); - children = data[pos++]; - - for(int i = 0; i < children; i++) - { - keys[i] = unpackLong(data,pos); - pos += 8; - } - - pos += 8 * (order - children); - - for(int i = 0; i < children; i++) - { - pointers[i] = unpackLong(data,pos); - pos += 8; - } - } //}}} - - //{{{ packLong() method - private void packLong(long num, byte[] data, int offset) - { - data[offset + 0] = (byte)(num >>> 56); - data[offset + 1] = (byte)(num >>> 48); - data[offset + 2] = (byte)(num >>> 40); - data[offset + 3] = (byte)(num >>> 32); - data[offset + 4] = (byte)(num >>> 24); - data[offset + 5] = (byte)(num >>> 16); - data[offset + 6] = (byte)(num >>> 8); - data[offset + 7] = (byte)(num >>> 0); - } //}}} - - //{{{ write() method - void write(RandomAccessFile out) throws IOException - { - byte[] data = new byte[getSize(order)]; - - int pos = 0; - data[pos++] = (byte)(leaf ? 1 : 0); - data[pos++] = (byte)children; - - for(int i = 0; i < children; i++) - { - packLong(keys[i],data,pos); - pos += 8; - } - - pos += 8 * (order - children); - - for(int i = 0; i < children; i++) - { - packLong(pointers[i],data,pos); - pos += 8; - } - - out.seek(offset); - out.write(data); - } //}}} - - //{{{ add() method - /** - * @exception BTreeException on various errors that should not occur - */ - void add(long key, long pointer) throws BTreeException - { - if(BTreeStore.DEBUG) - { - System.err.println("add " + key + "=" + pointer + " to"); - System.err.println(this); - } - - if(children == order) - throw new BTreeException("Node full"); - - int position = lookupInternal(key); - - if(keys[position] == key && position != children) - throw new BTreeException("Adding twice"); - - // shift the keys along - for(int i = children - 1; i >= position; i--) - { - keys[i + 1] = keys[i]; - pointers[i + 1] = pointers[i]; - } - - keys[position] = key; - pointers[position] = pointer; - - children++; - } //}}} - - //{{{ lookupExternal() method - int lookupExternal(long key) - { - for(int i = 0; i < children; i++) - { - if(key == keys[i]) - return i; - } - - return -1; - } //}}} - - //{{{ lookupInternal() method - int lookupInternal(long key) - { - for(int i = 0; i < children; i++) - { - if(key <= keys[i]) - return i; - } - - return children; - } //}}} - - //{{{ updateHighest() method - void updateHighest(long key) - { - keys[children - 1] = key; - } //}}} - - //{{{ split() method - int split(BTreeNode x, BTreeNode y, long key, boolean leaf) - { - x.leaf = leaf; - y.leaf = leaf; - - int median = children / 2; - - x.children = children - median; - y.children = median; - - if(order % 2 == 0) - median--; - - for(int i = 0; i < x.children; i++) - { - x.keys[i] = keys[i]; - x.pointers[i] = pointers[i]; - } - - for(int i = 0; i < y.children; i++) - { - y.keys[i] = keys[x.children + i]; - y.pointers[i] = pointers[x.children + i]; - } - - return median; - } //}}} - - //{{{ toString() method - public String toString() - { - StringBuffer buf = new StringBuffer(leaf ? "#{ " : "{ "); - for(int i = 0; i < children; i++) - { - buf.append(keys[i]); - buf.append("="); - buf.append(pointers[i]); - buf.append(" "); - } - return buf.append("}").toString(); - } //}}} - - //{{{ dump() method - public void dump(int indent) - { - StringBuffer buf = new StringBuffer(); - for(int i = 0; i < indent; i++) - buf.append(' '); - buf.append(toString()); - System.err.println(buf); - } //}}} -} diff --git a/factor/db/BTreeStore.java b/factor/db/BTreeStore.java deleted file mode 100644 index 052577db3d..0000000000 --- a/factor/db/BTreeStore.java +++ /dev/null @@ -1,653 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import java.io.*; - -/** - * A store that puts all records inside a single file on disk, indexed - * by a B-tree. - * - * B-Tree index header: - * - * INDEX_MAGIC - * 8 bytes - offset of root - * 1 byte - order - * 1 byte - dirty - set when loading, cleared when closing - * 4 bytes - height - * 8 bytes - maximum key - * - * Each record in data file: - * - * 8 bytes - key - * 4 bytes - length - * ... data follows - * - * Records in index file - see BTreeNode - */ -public class BTreeStore implements Store -{ - public static boolean DEBUG = false; - private static final int INDEX_MAGIC = 0xcabba4e4; - private static final int DATA_MAGIC = 0xdeadbeef; - - private static final int DEFAULT_ORDER = 64; - - private File indexFile; - private RandomAccessFile index; - private File dataFile; - private RandomAccessFile data; - - // header has INDEX_MAGIC + these 3 values packed - private long rootPointer; - private byte order; - private byte dirty; // non-zero if dirty - private int height; // height of the tree - private long maximumKey = -1; - - // root is always in memory - private BTreeNode root; - - private BTreeNode[] lookup; - - // next offset in the index file - private long nextOffset; - - //{{{ BTreeStore() method - /** - * Constructor used by FactorInterpreter when parsing -db parameter. - */ - public BTreeStore(String spec) - throws IOException, PersistenceException - { - int index = spec.lastIndexOf(':'); - byte order; - if(index == -1) - order = DEFAULT_ORDER; - else - { - order = Byte.parseByte(spec.substring(index + 1)); - spec = spec.substring(0,index); - } - - init(new File(spec),order,spec.startsWith("ro:")); - } //}}} - - //{{{ BTreeStore() method - public BTreeStore(File dataFile, byte order, boolean readOnly) - throws IOException, PersistenceException - { - init(dataFile,order,readOnly); - } //}}} - - //{{{ init() method - private void init(File dataFile, byte order, boolean readOnly) - throws IOException, PersistenceException - { - if(order <= 3) - throw new BTreeException("order must be > 3, < 127"); - - this.indexFile = new File(dataFile.getParent(), - dataFile.getName() + ".index"); - this.dataFile = dataFile; - - boolean indexFileExists = indexFile.exists(); - boolean dataFileExists = dataFile.exists(); - - index = new RandomAccessFile(indexFile, - readOnly ? "r" : "rw"); - data = new RandomAccessFile(dataFile, - readOnly ? "r" : "rw"); - - try - { - if(!indexFileExists || !dataFileExists) - { - this.order = order; - writeHeader(); - nextOffset = index.length(); - if(dataFileExists) - createIndex(); - } - else - { - readHeader(); - if(rootPointer != 0) - root = readNode(rootPointer); - } - } - catch(IOException e) - { - index.close(); - data.close(); - throw e; - } - catch(PersistenceException e) - { - index.close(); - data.close(); - throw e; - } - } //}}} - - //{{{ writeHeader() method - private void writeHeader() throws IOException - { - index.seek(0); - index.writeInt(INDEX_MAGIC); - index.writeByte(dirty); - index.writeLong(rootPointer); - index.writeByte(order); - index.writeInt(height); - } //}}} - - //{{{ readHeader() method - private void readHeader() throws IOException, PersistenceException - { - index.seek(0); - if(index.readInt() != INDEX_MAGIC) - throw new BTreeException("Bad magic number in index file"); - dirty = index.readByte(); - rootPointer = index.readLong(); - order = index.readByte(); - if(order < 3) - throw new BTreeException("Bad order"); - height = index.readInt(); - - nextOffset = index.length(); - } //}}} - - //{{{ createIndex() method - private void createIndex() throws IOException, PersistenceException - { - System.err.println("Re-creating index..."); - - data.seek(0); - - for(;;) - { - long offset = data.getFilePointer(); - - if(offset == data.length()) - { - // we're done - break; - } - - int magic = data.readInt(); - if(magic != DATA_MAGIC) - throw new BTreeException(magic + " != " + DATA_MAGIC); - - long key = data.readLong(); - int length = data.readInt(); - - saveToIndex(key,offset); - - data.skipBytes(length); - } - - System.err.println("... done"); - } //}}} - - //{{{ readNode() method - private BTreeNode readNode(long offset) throws IOException - { - BTreeNode node = new BTreeNode(order,offset); - node.read(index); - return node; - } //}}} - - //{{{ writeNode() method - private void writeNode(BTreeNode node) - throws IOException, BTreeException - { - if(DEBUG) - { - System.err.println("node.offset=" + node.offset - + ",index.length()=" + index.length()); - if(node.offset < index.length()) - { - BTreeNode existing = readNode(node.offset); - if(existing.leaf != node.leaf - // if children is zero, empty space! - && existing.children != 0) - { - throw new BTreeException("Overwriting " - + existing + " with " - + node); - } - } - } - - node.dirty = false; - node.write(index); - } //}}} - - //{{{ dump() method - private void dump(BTreeNode node, int indent) - throws IOException - { - node.dump(indent); - if(node.leaf) - return; - - indent++; - - for(int i = 0; i < node.children; i++) - dump(readNode(node.pointers[i]),indent); - } //}}} - - //{{{ dump() method - private void dump() - throws IOException - { - System.err.println("<<<< dump"); - if(root != null) - dump(root,0); - System.err.println(">>>>"); - } //}}} - - //{{{ checkOffset() method - private void checkOffset(long offset) - throws IOException, BTreeException - { - if(offset > nextOffset) - throw new BTreeException("Invalid pointer: " + offset + " > " + nextOffset); - } //}}} - - //{{{ lookup() method - /** - * Look up the given key, traversing down the tree. Returns an array - * of all nodes, from the root down, that were traversed. - * - * Note that when adding nodes to the B-tree, I 'cheat' by splitting on - * the way down any nodes with order == children. While this ends up - * splitting a few more nodes than strictly necessary, it avoids a - * second traversal up the tree, and simplifies the code. - - * @param add in add mode, nodes along the way are split if they would - * overflow. - * @param newMaximum if add is true *and* this is true, a new maximal - * node is being added, so the rightmost key in each node along the way - * needs to be updated. - */ - private void lookup(long key, boolean add, boolean newMaximum) - throws IOException, BTreeException - { - if(DEBUG) - System.err.println("HEIGHT = " + height); - - if(lookup == null || lookup.length != height) - { - saveLookup(); - lookup = new BTreeNode[height]; - } - - if(height != 0) - { - - /* - if this is true, a new level has been added (ie, the - root was split). we return this value instead of - incrementing the levels variable directly, since the old - value of 'levels' is needed until the end of the method. - */ - boolean newLevel = false; - - lookup[0] = root; - - if(add) - { - if(possiblySplitAndUpdateMax(0,newMaximum,key)) - newLevel = true; - } - - for(int i = 1; i < height; i++) - { - if(DEBUG) - System.err.println("Level " + i); - BTreeNode node = lookup[i - 1]; - if(node.leaf) - throw new BTreeException("A leaf: " + node); - int next = node.lookupInternal(key); - if(next == node.children) - next--; - - // read this node, and split it if we need to. - long offset = node.pointers[next]; - checkOffset(offset); - - // is the node already loaded? - if(lookup[i] == null) - lookup[i] = readNode(offset); - else if(lookup[i].offset != offset) - { - if(lookup[i].dirty) - writeNode(lookup[i]); - lookup[i] = readNode(offset); - } - - if(add) - { - if(possiblySplitAndUpdateMax(i,newMaximum,key)) - newLevel = true; - } - } - - // now that the above loop (indexed by 'levels') is - // done, we can increment the variable, and update the - // index header on disk. - if(newLevel) - { - height++; - writeHeader(); - } - } - - BTreeNode last = lookup[lookup.length - 1]; - - if(!last.leaf) - throw new BTreeException("Not a leaf: " + last); - - if(DEBUG) - System.err.println("NOW height=" + height); - } //}}} - - //{{{ nextOffset() method - private long nextOffset() - { - long ret = nextOffset; - nextOffset += BTreeNode.getSize(order); - return ret; - } //}}} - - //{{{ possiblySplitAndUpdateMax() method - /** - * The most important method of the B-tree class. - * If the number of keys in the node is equal to the order, split the - * node, and update the maximum key if necessary. - */ - private boolean possiblySplitAndUpdateMax( - int level, - boolean newMaximum, - long key) - throws IOException, BTreeException - { - BTreeNode node = lookup[level]; - long offset = node.offset; - - // see comment in findLeaf() to see why this is needed. - boolean newLevel = false; - - // will we split? - boolean split = (node.children == order); - - if(split) - { - BTreeNode left = new BTreeNode(order,0); - BTreeNode right = new BTreeNode(order,0); - - // split the node along the median into left and right - // side of median. store the left side in a new index - // record. - int median = node.split(left,right,key, - level == height - 1); - - if(DEBUG) - { - System.err.println("Splitting " + node); - System.err.println("==> left = " + left); - System.err.println("==> right = " + right); - } - - long medianKey = node.keys[median]; - long highestInLeft = medianKey; - - long leftOffset = nextOffset(); - if(DEBUG) - System.err.println("leftOffset=" + leftOffset); - - // the key we're adding might be in the left or right - // side of the split, so act accordingly. - if(key < medianKey) - { - if(DEBUG) - System.err.println("node=left"); - node = left; - right.offset = offset; - writeNode(right); - offset = leftOffset; - } - else - { - if(DEBUG) - System.err.println("node=right"); - left.offset = leftOffset; - writeNode(left); - node = right; - } - - if(level == 0) - { - if(DEBUG) - System.err.println("ROOT SPLIT"); - // we just split the root. create a new root - BTreeNode newRoot = new BTreeNode(order, - nextOffset()); - checkOffset(leftOffset); - newRoot.add(highestInLeft,leftOffset); - checkOffset(rootPointer); - newRoot.add(maximumKey,rootPointer); - writeNode(newRoot); - rootPointer = newRoot.offset; - root = newRoot; - newLevel = true; - } - else - { - if(DEBUG) - System.err.println("NODE SPLIT"); - // we just split a non-root node, update its - // parent. - BTreeNode parent = lookup[level - 1]; - // note that this will never fail, since if the - // parent previously had order == numKeys, it - // will already have been split - checkOffset(leftOffset); - parent.add(highestInLeft,leftOffset); - parent.dirty = true; - } - - node.dirty = true; - } - - // is this key we're adding a new maximum? - if(newMaximum && level != height - 1) - { - node.dirty = true; - node.updateHighest(key); - } - - // store node back in the 'nodes' array, after any changes have - // been made. - lookup[level] = node; - node.offset = offset; - - return newLevel; - } //}}} - - //{{{ exists() method - public boolean exists(long key) throws IOException, BTreeException - { - // empty tree? - if(height == 0) - return false; - - lookup(key,false,false); - return lookup[height - 1].lookupExternal(key) != -1; - } //}}} - - //{{{ loadFromData() method - /** - * Load a record from the data file. - */ - private byte[] loadFromData(long offset, long key) - throws IOException, BTreeException - { - data.seek(offset); - - int magic = data.readInt(); - if(magic != DATA_MAGIC) - throw new BTreeException(magic + " != " + DATA_MAGIC); - - if(data.readLong() != key) - throw new BTreeException("Record " + key + " not stored at " + offset); - int length = data.readInt(); - byte[] value = new byte[length]; - data.readFully(value); - return value; - } //}}} - - //{{{ loadFromStore() method - /** - * Load a record from the database with the given ID. - */ - public byte[] loadFromStore(long key) - throws IOException, PersistenceException - { - lookup(key,false,false); - BTreeNode last = lookup[height - 1]; - int index = last.lookupExternal(key); - if(index == -1) - throw new NoSuchRecordException(key); - long offset = last.pointers[index]; - return loadFromData(offset,key); - } //}}} - - //{{{ saveToData() method - /** - * Append a record to the data file. - */ - private long saveToData(long key, byte[] value) throws IOException - { - long offset = data.length(); - data.seek(offset); - data.writeInt(DATA_MAGIC); - data.writeLong(key); - data.writeInt(value.length); - data.write(value); - return offset; - } //}}} - - //{{{ saveToIndex() method - private void saveToIndex(long key, long offset) - throws IOException, PersistenceException - { - if(DEBUG) - dump(); - - // Do we need to update the maximum keys as we go along? - boolean newMaximum = (key > maximumKey); - if(newMaximum) - maximumKey = key; - - BTreeNode leaf; - - if(rootPointer == 0) - { - rootPointer = nextOffset(); - root = new BTreeNode(order,rootPointer); - root.leaf = true; - leaf = root; - height = 1; - } - else - { - int last = height - 1; - lookup(key,true,newMaximum); - leaf = lookup[last]; - } - - // add the node to the leaf, write the leaf back to disk. - int existing = leaf.lookupExternal(key); - if(existing == -1) - { - // new record - leaf.add(key,offset); - } - else - { - // updating existing record - leaf.pointers[existing] = offset; - } - - leaf.dirty = true; - writeNode(leaf); - } //}}} - - //{{{ saveToStore() method - /** - * Save a record to the database with the given ID. - */ - public void saveToStore(long key, byte[] value) - throws IOException, PersistenceException - { - long offset = saveToData(key,value); - - saveToIndex(key,offset); - } //}}} - - //{{{ saveLookup() method - /** - * Save all nodes in the lookup array. - */ - private void saveLookup() throws IOException, BTreeException - { - if(lookup == null) - return; - - for(int i = 0; i < lookup.length; i++) - { - if(lookup[i].dirty) - writeNode(lookup[i]); - } - } //}}} - - //{{{ close() method - /** - * Close the store. - */ - public void close() throws IOException, BTreeException - { - saveLookup(); - index.close(); - data.close(); - } //}}} -} diff --git a/factor/db/FileStore.java b/factor/db/FileStore.java deleted file mode 100644 index f4d780da62..0000000000 --- a/factor/db/FileStore.java +++ /dev/null @@ -1,119 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import java.io.*; - -/** - * A store that puts all records as files inside a directory. - */ -public class FileStore implements Store -{ - private File directory; - - //{{{ FileStore() method - public FileStore(String directory) - { - this(new File(directory)); - } //}}} - - //{{{ FileStore() method - public FileStore(File directory) - { - this.directory = directory; - directory.mkdirs(); - } //}}} - - //{{{ exists() method - public boolean exists(long id) - { - return new File(directory,String.valueOf(id)).exists(); - } //}}} - - //{{{ loadFromStore() method - /** - * Load a record from the database with the given ID. - */ - public byte[] loadFromStore(long key) - throws IOException, PersistenceException - { - if(!exists(key)) - throw new NoSuchRecordException(key); - return readFile(new File(directory,String.valueOf(key))); - } //}}} - - //{{{ readFile() method - private byte[] readFile(File file) throws IOException - { - DataInputStream in = new DataInputStream( - new FileInputStream(file)); - byte[] buf = new byte[(int)file.length()]; - try - { - in.readFully(buf); - } - finally - { - in.close(); - } - return buf; - } //}}} - - //{{{ saveToStore() method - /** - * Save a record to the database with the given ID. - */ - public void saveToStore(long key, byte[] value) throws IOException - { - writeFile(new File(directory,String.valueOf(key)),value); - } //}}} - - //{{{ writeFile() method - private void writeFile(File file, byte[] content) throws IOException - { - FileOutputStream out = new FileOutputStream(file); - try - { - out.write(content,0,content.length); - } - finally - { - out.close(); - } - } //}}} - - //{{{ close() method - /** - * Close the store. - */ - public void close() throws IOException, PersistenceException - { - } //}}} -} diff --git a/factor/db/NoSuchRecordException.java b/factor/db/NoSuchRecordException.java deleted file mode 100644 index 45e8d670b1..0000000000 --- a/factor/db/NoSuchRecordException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -public class NoSuchRecordException extends PersistenceException -{ - public NoSuchRecordException(long id) - { - super("No such record: " + id); - } -} diff --git a/factor/db/PersistenceException.java b/factor/db/PersistenceException.java deleted file mode 100644 index 0f0eb37b43..0000000000 --- a/factor/db/PersistenceException.java +++ /dev/null @@ -1,50 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import factor.FactorException; - -public class PersistenceException extends FactorException -{ - public PersistenceException() - { - super(); - } - - public PersistenceException(String msg) - { - super(msg); - } - - public PersistenceException(String msg, Throwable t) - { - super(msg,t); - } -} diff --git a/factor/db/PersistentBinary.java b/factor/db/PersistentBinary.java deleted file mode 100644 index 71b8f2e243..0000000000 --- a/factor/db/PersistentBinary.java +++ /dev/null @@ -1,116 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import factor.Cons; -import factor.FactorInterpreter; - -/** - * A simple wrapper around a byte array stored in the object database. - */ -public class PersistentBinary implements PersistentObject -{ - private Workspace workspace; - private long id; - private byte[] bytes; - - //{{{ PersistentBinary constructor - public PersistentBinary(Workspace workspace, byte[] bytes) - throws Exception - { - this(workspace,workspace == null ? 0L : workspace.nextID()); - this.bytes = bytes; - } //}}} - - //{{{ PersistentBinary constructor - public PersistentBinary(Workspace workspace, long id) throws Exception - { - this.workspace = workspace; - this.id = id; - - if(workspace != null && id != 0L) - workspace.put(this); - } //}}} - - //{{{ getBytes() method - public byte[] getBytes() - { - return bytes; - } //}}} - - //{{{ getWorkspace() method - /** - * Each persistent object is stored in one workspace only. - */ - public Workspace getWorkspace() - { - return workspace; - } //}}} - - //{{{ getID() method - /** - * Each persistent object has an associated ID. - */ - public long getID() - { - return id; - } //}}} - - //{{{ pickle() method - /** - * Each persistent object can turn itself into a byte array. - */ - public byte[] pickle() - { - return bytes; - } //}}} - - //{{{ unpickle() method - /** - * Each persistent object can set its state to that in a byte array. - */ - public void unpickle(byte[] bytes, int offset) - { - if(offset == 0) - this.bytes = bytes; - else - { - int len = bytes.length - offset; - this.bytes = new byte[len]; - System.arraycopy(bytes,offset,this.bytes,0,len); - } - } //}}} - - //{{{ getReferences() method - public Cons getReferences() - { - return null; - } //}}} -} diff --git a/factor/db/PersistentIgnore.java b/factor/db/PersistentIgnore.java deleted file mode 100644 index 2fbd874d10..0000000000 --- a/factor/db/PersistentIgnore.java +++ /dev/null @@ -1,38 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import factor.FactorInterpreter; - -/** - * Any objects implementing this interface are written to the database - * as f. - */ -public interface PersistentIgnore {} diff --git a/factor/db/PersistentObject.java b/factor/db/PersistentObject.java deleted file mode 100644 index 9ab7c6aff2..0000000000 --- a/factor/db/PersistentObject.java +++ /dev/null @@ -1,63 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import factor.Cons; -import factor.FactorInterpreter; - -public interface PersistentObject -{ - /** - * Each persistent object is stored in one workspace only. - */ - public Workspace getWorkspace(); - - /** - * Each persistent object has an associated ID. - */ - public long getID(); - - /** - * Each persistent object can turn itself into a byte array. - */ - public byte[] pickle() - throws PersistenceException; - - /** - * Each persistent object can set its state to that in a byte array. - */ - public void unpickle(byte[] bytes, int offset) - throws PersistenceException; - - /** - * Used for storage compaction. - */ - public Cons getReferences(); -} diff --git a/factor/db/ResourceStore.java b/factor/db/ResourceStore.java deleted file mode 100644 index b22fdb8f07..0000000000 --- a/factor/db/ResourceStore.java +++ /dev/null @@ -1,86 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import factor.FactorLib; -import java.io.*; - -/** - * A store that reads records from the class path. - */ -public class ResourceStore implements Store -{ - private String directory; - - //{{{ ResourceStore() method - public ResourceStore(String directory) - { - this.directory = directory; - } //}}} - - //{{{ exists() method - public boolean exists(long key) - { - return getClass().getResource(directory + key) != null; - } //}}} - - //{{{ loadFromStore() method - /** - * Load a record from the database with the given ID. - */ - public byte[] loadFromStore(long key) - throws IOException, PersistenceException - { - if(!exists(key)) - throw new NoSuchRecordException(key); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - FactorLib.copy(getClass().getResourceAsStream( - directory + key),out); - return out.toByteArray(); - } //}}} - - //{{{ saveToStore() method - /** - * Save a record to the database with the given ID. - */ - public void saveToStore(long key, byte[] value) throws IOException - { - throw new IOException("Read only store"); - } //}}} - - //{{{ close() method - /** - * Close the store. - */ - public void close() - { - } //}}} -} diff --git a/factor/db/SimplePersistentObject.java b/factor/db/SimplePersistentObject.java deleted file mode 100644 index 4ec3625b33..0000000000 --- a/factor/db/SimplePersistentObject.java +++ /dev/null @@ -1,124 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2003 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import factor.compiler.*; -import factor.*; -import java.util.*; - -/** - * An object that persists to a name/value list. - */ -public class SimplePersistentObject implements FactorObject, - PersistentObject -{ - protected Workspace workspace; - protected long id; - protected Table table; - - //{{{ SimplePersistentObject constructor - public SimplePersistentObject() - { - try - { - table = new Table(this); - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } //}}} - - //{{{ SimplePersistentObject constructor - public SimplePersistentObject(Workspace workspace, long id) - throws Exception - { - this.workspace = workspace; - this.id = id; - table = new Table(this,workspace,0L); - } //}}} - - //{{{ SimplePersistentObject constructor - public SimplePersistentObject(Workspace workspace) throws Exception - { - this(workspace,workspace == null ? 0L : workspace.nextID()); - } //}}} - - //{{{ getWorkspace() method - /** - * Each persistent object is stored in one workspace only. - */ - public Workspace getWorkspace() - { - return workspace; - } //}}} - - //{{{ getID() method - /** - * Each persistent object has an associated ID. - */ - public long getID() - { - return id; - } //}}} - - //{{{ pickle() method - /** - * Each persistent object can turn itself into a byte array. - */ - public byte[] pickle() - throws PersistenceException - { - return table.pickle(); - } //}}} - - //{{{ unpickle() method - /** - * Each persistent object can set its state to that in a byte array. - */ - public void unpickle(byte[] bytes, int offset) - throws PersistenceException - { - table.unpickle(bytes,offset); - } //}}} - - //{{{ getNamespace() method - public FactorNamespace getNamespace() - throws Exception - { - return table; - } //}}} - - //{{{ getReferences() method - public Cons getReferences() - { - return table.getReferences(); - } //}}} -} diff --git a/factor/db/Store.java b/factor/db/Store.java deleted file mode 100644 index 859c58b4cf..0000000000 --- a/factor/db/Store.java +++ /dev/null @@ -1,59 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import java.io.IOException; - -/** - * The low-level interface to a persistent store. - * It can retreive and store string values, keyed by string identifiers. - */ -public interface Store -{ - public boolean exists(long id) - throws IOException, PersistenceException; - - /** - * Load a record from the database with the given ID. - */ - public byte[] loadFromStore(long key) - throws IOException, PersistenceException; - - /** - * Save a record to the database with the given ID. - */ - public void saveToStore(long key, byte[] value) - throws IOException, PersistenceException; - - /** - * Close the store. - */ - public void close() throws IOException, PersistenceException; -} diff --git a/factor/db/Table.java b/factor/db/Table.java deleted file mode 100644 index 6edbfa491e..0000000000 --- a/factor/db/Table.java +++ /dev/null @@ -1,381 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import factor.*; -import java.io.*; -import java.util.Map; -import java.util.TreeMap; - -/** - * A table is a persistent namespace. - * - * The picked format is as follows: - * - * 4 bytes -- number of rows - * Each row: - * 4 bytes -- length of name - * x bytes -- name - * 4 bytes -- length of value - * x bytes -- unparsed value - * 1 byte -- newline - * - * All strings are stored as UTF8. - */ -public class Table extends FactorNamespace implements PersistentObject -{ - public static boolean DEBUG = false; - public static final String ENCODING = "UTF8"; - - private Workspace workspace; - private long id; - - //{{{ Table constructor - public Table() - { - } //}}} - - //{{{ Table constructor - public Table(Workspace workspace) throws Exception - { - this(workspace,workspace == null ? 0L : workspace.nextID()); - } //}}} - - //{{{ Table constructor - public Table(Workspace workspace, long id) throws Exception - { - this.workspace = workspace; - this.id = id; - - if(workspace != null && id != 0L) - workspace.put(this); - } //}}} - - //{{{ Table constructor - public Table(Object obj) throws Exception - { - super(obj); - } //}}} - - //{{{ Table constructor - public Table(Object obj, Workspace workspace) throws Exception - { - this(obj,workspace,workspace == null ? 0L : workspace.nextID()); - } //}}} - - //{{{ Table constructor - public Table(Object obj, Workspace workspace, long id) throws Exception - { - super(obj); - this.workspace = workspace; - this.id = id; - - if(workspace != null && id != 0L) - workspace.put(this); - } //}}} - - //{{{ Table constructor - /** - * Cloning constructor. - */ - public Table(Map words, Object obj, Workspace workspace) - throws Exception - { - super(words,obj); - - this.workspace = workspace; - - if(workspace != null) - { - this.id = workspace.nextID(); - workspace.put(this); - } - } //}}} - - //{{{ getWorkspace() method - /** - * Each persistent object is stored in one workspace only. - */ - public Workspace getWorkspace() - { - return workspace; - } //}}} - - //{{{ getID() method - /** - * Each persistent object has an associated ID. - */ - public long getID() - { - return id; - } //}}} - - //{{{ pickleValue() method - private synchronized String pickleValue(String name) - throws Exception - { - Object valueObj = words.get(name); - - if(valueObj == null) - { - lazyFieldInit(name); - valueObj = words.get(name); - } - - String value; - - if(valueObj instanceof Pickled) - { - value = ((Pickled)valueObj) - .getUnparsed(); - } - else - { - value = FactorReader.unparseDBObject( - getVariable(name)); - } - - return value; - } //}}} - - //{{{ pickle() method - /** - * Each persistent object can turn itself into a byte array. - */ - public synchronized byte[] pickle() - throws PersistenceException - { - try - { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(bytes); - - Cons values = toVarList(); - - if(values == null) - out.writeInt(0); - else - out.writeInt(values.length()); - - while(values != null) - { - String name = (String)values.car; - out.writeInt(name.length()); - byte[] nameBytes = name.getBytes(ENCODING); - out.write(nameBytes); - - String value = pickleValue(name); - - out.writeInt(value.length()); - byte[] valueBytes = value.getBytes(ENCODING); - out.write(valueBytes); - - out.write('\n'); - - values = values.next(); - } - - return bytes.toByteArray(); - } - catch(Exception e) - { - // should not happen with byte array stream - throw new PersistenceException("Unexpected error",e); - } - } //}}} - - //{{{ unpickle() method - /** - * Each persistent object can set its state to that in a byte array. - */ - public synchronized void unpickle(byte[] bytes, int offset) - throws PersistenceException - { - try - { - ByteArrayInputStream bin = new ByteArrayInputStream(bytes); - bin.skip(offset); - DataInputStream in = new DataInputStream(bin); - - int count = in.readInt(); - - for(int i = 0; i < count; i++) - { - int nameLength = in.readInt(); - byte[] nameBytes = new byte[nameLength]; - in.readFully(nameBytes); - - String name = new String(nameBytes,ENCODING); - - int valueLength = in.readInt(); - - byte[] valueBytes = new byte[valueLength]; - in.readFully(valueBytes); - - // skip newline at the end - in.readByte(); - - String value = new String(valueBytes,ENCODING); - - Object obj = words.get(name); - if(obj == null) - { - lazyFieldInit(name); - obj = words.get(name); - } - - if(obj instanceof VarBinding) - { - try - { - setVariable(name,FactorReader.parseObject( - value,workspace.getInterpreter())); - } - catch(Exception e) - { - //XXX: what to do here - System.err.println("Unexpected error when setting " + name + " to " + value); - e.printStackTrace(); - } - } - else - { - // super becaue we don't want this to add the - // table to the save queue - super.setVariable(name,new Pickled(value)); - } - } - } - catch(Exception e) - { - // should not happen with byte array stream - throw new PersistenceException("Unexpected error",e); - } - } //}}} - - //{{{ getVariable() method - public synchronized Object getVariable(String name) throws Exception - { - Object value = super.getVariable(name); - if(value instanceof Pickled) - { - try - { - if(DEBUG) - System.err.println(this + ".getVariable(" + name + "): " - + value); - - value = FactorReader.parseObject(((Pickled)value) - .getUnparsed(),workspace.getInterpreter()); - } - catch(Exception e) - { - throw new FactorRuntimeException("Table " + getID() + " has unreadable values",e); - } - - // super becaue we don't want this to add the table - // to the save queue - super.setVariable(name,value); - } - return value; - } //}}} - - //{{{ setVariable() method - public synchronized void setVariable(String name, Object value) - throws Exception - { - super.setVariable(name,value); - if(workspace != null && id != 0L) - workspace.put(this); - } //}}} - - //{{{ clone() method - public FactorNamespace clone(Object rebind) - { - if(rebind.getClass() != obj.getClass()) - throw new RuntimeException("Cannot rebind to different type"); - - try - { - return new Table(words,rebind,workspace); - } - catch(Exception e) - { - throw new InternalError(); - } - } //}}} - - //{{{ clone() method - public Object clone() - { - if(obj != null) - throw new RuntimeException("Cannot clone namespace that's bound to an object"); - - try - { - return new Table(new TreeMap(words),null,workspace); - } - catch(Exception e) - { - throw new InternalError(); - } - } //}}} - - //{{{ Pickled class - /** - * We lazily parse values in tables. An unparsed value is represented - * by an instance of this class. - */ - static class Pickled - { - private String unparsed; - - Pickled(String unparsed) - { - this.unparsed = unparsed; - } - - String getUnparsed() - { - return unparsed; - } - - public String toString() - { - return unparsed; - } - } //}}} - - //{{{ getReferences() method - public synchronized Cons getReferences() - { - return new Cons(getThis(),toVarList()); - } //}}} -} diff --git a/factor/db/Workspace.java b/factor/db/Workspace.java deleted file mode 100644 index 957684d0fa..0000000000 --- a/factor/db/Workspace.java +++ /dev/null @@ -1,517 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.db; - -import factor.*; -import java.io.*; -import java.lang.ref.WeakReference; -import java.util.*; - -/** - * A workspace is an orthogonal persistence store. - * - * Record format is: - * - 1 byte: name length - * - n bytes: class name - * - remainder: bytes passed to new instance unpickle() - */ -public class Workspace -{ - /** - * A map of WeakReferences. All instances of this class are stored - * here. - */ - private static Map instances = new WeakHashMap(); - - private static WorkspaceSaveDaemon flushThread = new WorkspaceSaveDaemon(); - public static boolean LOAD_DEBUG = false; - public static boolean SAVE_DEBUG = false; - - /** - * The ID of the header record. A value never returned by - * nextID(). - */ - public static final long HEADER = -1; - - public static final String DB_VERSION = "1.0"; - public static int flushInterval = 5000; - - /** - * In a read-only workspace, changes are silently discarded on - * shutdown. - */ - private boolean readOnly; - - private Store store; - private FactorInterpreter interp; - private HashSet saveQueue; - - /** - * Floating objects are currently in-memory. - * This map maps IDs to WeakReferences. - */ - private Map floating; - - /** - * Table containing important values. Always in memory. - */ - private Table header; - - /** - * For resolving circular references, currently loading objects. - */ - private Map loading; - - private boolean closed; - - /** - * Track all IDs handed out with nextID(), and make sure they - * eventually reach the store. - */ - private Set pendingIDs = new TreeSet(); - - //{{{ Workspace constructor - public Workspace(Store store, boolean readOnly, - FactorInterpreter interp) - throws Exception - { - this.store = store; - this.readOnly = readOnly; - this.interp = interp; - floating = new HashMap(); - saveQueue = new HashSet(); - loading = new HashMap(); - - if(store.exists(HEADER)) - header = (Table)get(HEADER); - else - { - header = new Table(this,HEADER); - initHeader(); - } - - instances.put(this,Boolean.TRUE); - } //}}} - - //{{{ isFirstTime() method - public boolean isFirstTime() - { - try - { - return header.getVariable("first-time") != null; - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } //}}} - - //{{{ setFirstTime() method - public void setFirstTime(boolean firstTime) - { - try - { - header.setVariable("first-time",firstTime - ? Boolean.TRUE : null); - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } //}}} - - //{{{ isReadOnly() method - /** - * In a 'read only' workspace, changes are silently discarded when - * the workspace is closed. - */ - public boolean isReadOnly() - { - return readOnly; - } //}}} - - //{{{ initHeader() method - public void initHeader() throws Exception - { - header.setVariable("nextID",new Long(0)); - header.setVariable("root",new Table(this)); - header.setVariable("version",DB_VERSION); - header.setVariable("first-time",Boolean.TRUE); - } //}}} - - //{{{ getRoot() method - /** - * Returns the workspace root. - */ - public Table getRoot() - { - try - { - return (Table)header.getVariable("root"); - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } //}}} - - //{{{ getInterpreter() method - public FactorInterpreter getInterpreter() - { - return interp; - } //}}} - - //{{{ nextID() method - public synchronized long nextID()// throws PersistenceException - { - try - { - long nextID = FactorJava.toLong( - header.getVariable("nextID")); - if(nextID == Long.MAX_VALUE) - throw new RuntimeException("FIXME!"); - - nextID++; - - Long nextIDboxed = new Long(nextID); - header.setVariable("nextID",nextIDboxed); - pendingIDs.add(nextIDboxed); - return nextID; - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } //}}} - - //{{{ load() method - /** - * Load an object. - */ - private PersistentObject load(long id) - throws IOException, PersistenceException - { - PersistentObject circularRef = (PersistentObject) - loading.get(new Long(id)); - - if(circularRef != null) - return circularRef; - - if(LOAD_DEBUG) - System.err.println("Loading from store: " + id); - byte[] data = store.loadFromStore(id); - byte len = data[0]; - String className = new String(data,1,len,"ASCII"); - - // hack :-) - try - { - PersistentObject obj = (PersistentObject) - Class.forName(className) - .getConstructor(new Class[] { - Workspace.class, long.class - }).newInstance(new Object[] { - this, new Long(id) - }); - - loading.put(new Long(id),obj); - - obj.unpickle(data,len + 1); - return obj; - } - catch(PersistenceException p) - { - throw p; - } - catch(Exception e) - { - throw new PersistenceException("Unexpected error",e); - } - finally - { - loading.remove(new Long(id)); - } - } //}}} - - //{{{ loadToCache() method - /** - * Load an object with given ID and store it in the floating map. - */ - private PersistentObject loadToCache(long id) - throws IOException, PersistenceException - { - PersistentObject obj = load(id); - WeakReference ref = new WeakReference(obj); - floating.put(new Long(id),ref); - return obj; - } //}}} - - //{{{ get() method - /** - * If an object is already loaded, return that instance, otherwise - * load it. - */ - public synchronized PersistentObject get(long id) - throws IOException, PersistenceException - { - if(closed) - throw new PersistenceException(); - - WeakReference ref = (WeakReference)floating.get(new Long(id)); - if(ref == null) - return loadToCache(id); - else - { - PersistentObject obj = (PersistentObject)ref.get(); - if(obj == null) - return loadToCache(id); - else - { - if(LOAD_DEBUG) - System.err.println("Found cached: " + id); - return obj; - } - } - } //}}} - - //{{{ addToCache() method - private void addToCache(PersistentObject obj) - throws PersistenceException - { - if(obj.getWorkspace() != this) - throw new PersistenceException("Object from another workspace"); - - Long id = new Long(obj.getID()); - - WeakReference ref = (WeakReference)floating.get(id); - if(ref == null) - floating.put(id,new WeakReference(obj)); - else - { - Object referenced = ref.get(); - if(referenced != obj) - throw new PersistenceException(referenced + " != " + obj); - } - } //}}} - - //{{{ save() method - /** - * Store an object. - */ - private void save(PersistentObject obj) - throws IOException, PersistenceException - { - save(obj,store); - } //}}} - - //{{{ save() method - /** - * Store an object. - */ - private void save(PersistentObject obj, Store store) - throws IOException, PersistenceException - { - if(SAVE_DEBUG) - System.err.println("Saving object " + obj.getID()); - - if(readOnly) - throw new RuntimeException(); - - pendingIDs.remove(new Long(obj.getID())); - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - String className = obj.getClass().getName(); - bout.write((byte)className.length()); - bout.write(className.getBytes("ASCII")); - bout.write(obj.pickle()); - store.saveToStore(obj.getID(),bout.toByteArray()); - } //}}} - - //{{{ put() method - /** - * Add an object to the save queue. - */ - public synchronized void put(PersistentObject obj) - throws PersistenceException - { - if(closed) - throw new PersistenceException(); - - addToCache(obj); - saveQueue.add(obj); - } //}}} - - //{{{ flush() method - /** - * Write all pending unsaved objects to the store. - */ - public synchronized void flush() - throws IOException, PersistenceException - { - if(closed || readOnly) - return; - - Iterator iter = saveQueue.iterator(); - while(iter.hasNext()) - { - PersistentObject obj = (PersistentObject)iter.next(); - save(obj); - iter.remove(); - } - } //}}} - - //{{{ compact() method - /** - * Write all referencable objects to the given store. - */ - private void compact(Store store) - throws IOException, PersistenceException - { - Set open = new HashSet(); - Set closed = new HashSet(); - - for(;;) - { - if(open.isEmpty()) - break; - - Iterator iter = open.iterator(); - Object obj = iter.next(); - iter.remove(); - - closed.add(obj); - - Cons references; - if(obj instanceof PersistentObject) - { - PersistentObject pobj = (PersistentObject)obj; - save(pobj,store); - references = pobj.getReferences(); - } - else - references = (Cons)obj; - - while(references != null) - { - Object ref = references.car; - if((references.car instanceof PersistentObject - || references.car instanceof Cons) - && !closed.contains(references.car)) - { - open.add(references.car); - } - if(references.cdr instanceof Cons) - references = references.next(); - else - { - if(references.cdr != null - && - !closed.contains(references.car)) - { - open.add(references.cdr); - } - break; - } - } - } - } //}}} - - //{{{ close() method - /** - * Close the workspace. - */ - public synchronized void close() - throws IOException, PersistenceException - { - flush(); - - closed = true; - - if(pendingIDs.size() != 0) - { - System.err.println("The following IDs did not get saved:"); - System.err.println(pendingIDs); - } - - store.close(); - } //}}} - - //{{{ finalize() method - protected void finalize() throws Throwable - { - super.finalize(); - close(); - } //}}} - - //{{{ WorkspaceSaveDaemon class - static class WorkspaceSaveDaemon extends Thread - { - WorkspaceSaveDaemon() - { - setDaemon(true); - start(); - } - - public void run() - { - for(;;) - { - Iterator workspaces = instances.keySet().iterator(); - while(workspaces.hasNext()) - { - Workspace workspace = (Workspace) - workspaces.next(); - try - { - workspace.flush(); - } - catch(Exception e) - { - System.err.println("ERROR WHILE SAVING WORKSPACE."); - System.err.println("Workspace will be closed."); - synchronized(workspace) - { - workspace.closed = true; - } - e.printStackTrace(); - } - } - - try - { - Thread.sleep(flushInterval); - } - catch(InterruptedException e) - { - } - } - } - } //}}} -} diff --git a/factor/parser/Bar.java b/factor/parser/Bar.java index 53ac946d3c..193c6c6e27 100644 --- a/factor/parser/Bar.java +++ b/factor/parser/Bar.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Bar extends FactorParsingDefinition { @@ -38,10 +37,10 @@ public class Bar extends FactorParsingDefinition /** * A new definition. */ - public Bar(FactorWord word, Workspace workspace) + public Bar(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/Base.java b/factor/parser/Base.java index 0fafef7b60..97fac331ef 100644 --- a/factor/parser/Base.java +++ b/factor/parser/Base.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Base extends FactorParsingDefinition { @@ -40,10 +39,10 @@ public class Base extends FactorParsingDefinition /** * A new definition. */ - public Base(FactorWord word, Workspace workspace, int base) + public Base(FactorWord word, int base) throws Exception { - super(word,workspace); + super(word); this.base = base; } //}}} diff --git a/factor/parser/Bra.java b/factor/parser/Bra.java index 2a5a4a6f06..14a2097892 100644 --- a/factor/parser/Bra.java +++ b/factor/parser/Bra.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Bra extends FactorParsingDefinition { @@ -38,10 +37,10 @@ public class Bra extends FactorParsingDefinition /** * A new definition. */ - public Bra(FactorWord word, Workspace workspace) + public Bra(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/CharLiteral.java b/factor/parser/CharLiteral.java index 165e175906..53aa0ff35f 100644 --- a/factor/parser/CharLiteral.java +++ b/factor/parser/CharLiteral.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import java.io.IOException; public class CharLiteral extends FactorParsingDefinition @@ -39,20 +38,10 @@ public class CharLiteral extends FactorParsingDefinition /** * A new definition. */ - public CharLiteral(FactorWord word, Workspace workspace) + public CharLiteral(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ CharLiteral constructor - /** - * A blank definition, about to be unpickled. - */ - public CharLiteral(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/ComplexLiteral.java b/factor/parser/ComplexLiteral.java index f99e46ee59..d227b67d18 100644 --- a/factor/parser/ComplexLiteral.java +++ b/factor/parser/ComplexLiteral.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import factor.math.*; public class ComplexLiteral extends FactorParsingDefinition @@ -41,11 +40,10 @@ public class ComplexLiteral extends FactorParsingDefinition /** * A new definition. */ - public ComplexLiteral(FactorWord word, - String end, Workspace workspace) + public ComplexLiteral(FactorWord word, String end) throws Exception { - super(word,workspace); + super(word); this.end = end; } //}}} diff --git a/factor/parser/Def.java b/factor/parser/Def.java index cd016bcc23..c4064099e4 100644 --- a/factor/parser/Def.java +++ b/factor/parser/Def.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Def extends FactorParsingDefinition { @@ -38,10 +37,10 @@ public class Def extends FactorParsingDefinition /** * A new definition. */ - public Def(FactorWord word, Workspace workspace) + public Def(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/Defer.java b/factor/parser/Defer.java index 8422d31824..ac8382fed1 100644 --- a/factor/parser/Defer.java +++ b/factor/parser/Defer.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Defer extends FactorParsingDefinition { @@ -38,10 +37,10 @@ public class Defer extends FactorParsingDefinition /** * A new definition. */ - public Defer(FactorWord word, Workspace workspace) + public Defer(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/Dispatch.java b/factor/parser/Dispatch.java index abe596e1a3..524cf0d349 100644 --- a/factor/parser/Dispatch.java +++ b/factor/parser/Dispatch.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import java.io.IOException; public class Dispatch extends FactorParsingDefinition @@ -39,10 +38,10 @@ public class Dispatch extends FactorParsingDefinition /** * A new definition. */ - public Dispatch(FactorWord word, Workspace workspace) + public Dispatch(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/F.java b/factor/parser/F.java index 0ce1e92300..4af66b9cfe 100644 --- a/factor/parser/F.java +++ b/factor/parser/F.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class F extends FactorParsingDefinition { @@ -38,10 +37,10 @@ public class F extends FactorParsingDefinition /** * A new definition. */ - public F(FactorWord word, Workspace workspace) + public F(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/GetPersistentObject.java b/factor/parser/GetPersistentObject.java deleted file mode 100644 index 21f7d5a34d..0000000000 --- a/factor/parser/GetPersistentObject.java +++ /dev/null @@ -1,58 +0,0 @@ -/* :folding=explicit:collapseFolds=1: */ - -/* - * $Id$ - * - * Copyright (C) 2004 Slava Pestov. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package factor.parser; - -import factor.*; -import factor.db.*; -import java.io.IOException; - -public class GetPersistentObject extends FactorParsingDefinition -{ - //{{{ GetPersistentObject constructor - /** - * A new definition. - */ - public GetPersistentObject(FactorWord word, Workspace workspace) - throws Exception - { - super(word,workspace); - } //}}} - - public void eval(FactorInterpreter interp, FactorReader reader) - throws Exception - { - long id = FactorJava.toLong(reader.next(true,false)); - - if(interp.workspace == null) - reader.getScanner().error("No workspace"); - else - reader.append(interp.workspace.get(id)); - } -} diff --git a/factor/parser/In.java b/factor/parser/In.java index 57528070a8..42d02f8b5a 100644 --- a/factor/parser/In.java +++ b/factor/parser/In.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class In extends FactorParsingDefinition { @@ -38,10 +37,10 @@ public class In extends FactorParsingDefinition /** * A new definition. */ - public In(FactorWord word, Workspace workspace) + public In(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} //{{{ eval() method diff --git a/factor/parser/Ine.java b/factor/parser/Ine.java index c626869f97..137a69a96d 100644 --- a/factor/parser/Ine.java +++ b/factor/parser/Ine.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Ine extends FactorParsingDefinition { @@ -40,10 +39,10 @@ public class Ine extends FactorParsingDefinition /** * A new definition. */ - public Ine(FactorWord start, FactorWord end, Workspace workspace) + public Ine(FactorWord start, FactorWord end) throws Exception { - super(end,workspace); + super(end); this.start = start; } //}}} diff --git a/factor/parser/Ket.java b/factor/parser/Ket.java index cb8b222e4b..d10df15b5e 100644 --- a/factor/parser/Ket.java +++ b/factor/parser/Ket.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Ket extends FactorParsingDefinition { @@ -40,10 +39,10 @@ public class Ket extends FactorParsingDefinition /** * A new definition. */ - public Ket(FactorWord start, FactorWord end, Workspace workspace) + public Ket(FactorWord start, FactorWord end) throws Exception { - super(end,workspace); + super(end); this.start = start; } //}}} diff --git a/factor/parser/LineComment.java b/factor/parser/LineComment.java index e32d8cfe4f..3f5f6a3243 100644 --- a/factor/parser/LineComment.java +++ b/factor/parser/LineComment.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import java.io.IOException; public class LineComment extends FactorParsingDefinition @@ -41,10 +40,10 @@ public class LineComment extends FactorParsingDefinition /** * A new definition. */ - public LineComment(FactorWord word, boolean doc, Workspace workspace) + public LineComment(FactorWord word, boolean doc) throws Exception { - super(word,workspace); + super(word); this.doc = doc; } //}}} diff --git a/factor/parser/NoParsing.java b/factor/parser/NoParsing.java index 67ea4dbfd2..dfd3abe106 100644 --- a/factor/parser/NoParsing.java +++ b/factor/parser/NoParsing.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import java.io.IOException; public class NoParsing extends FactorParsingDefinition @@ -39,10 +38,10 @@ public class NoParsing extends FactorParsingDefinition /** * A new definition. */ - public NoParsing(FactorWord word, Workspace workspace) + public NoParsing(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/PassThrough.java b/factor/parser/PassThrough.java index d06d929636..b1cffd33c1 100644 --- a/factor/parser/PassThrough.java +++ b/factor/parser/PassThrough.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import java.io.IOException; public class PassThrough extends FactorParsingDefinition @@ -39,10 +38,10 @@ public class PassThrough extends FactorParsingDefinition /** * A new definition. */ - public PassThrough(FactorWord word, Workspace workspace) + public PassThrough(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/Shuffle.java b/factor/parser/Shuffle.java index 1f5325cf29..de30bb9269 100644 --- a/factor/parser/Shuffle.java +++ b/factor/parser/Shuffle.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Shuffle extends FactorParsingDefinition { @@ -40,10 +39,10 @@ public class Shuffle extends FactorParsingDefinition /** * A new definition. */ - public Shuffle(FactorWord word, String end, Workspace workspace) + public Shuffle(FactorWord word, String end) throws Exception { - super(word,workspace); + super(word); this.end = end; } //}}} diff --git a/factor/parser/StackComment.java b/factor/parser/StackComment.java index 5b2bb9f285..78ef702aa8 100644 --- a/factor/parser/StackComment.java +++ b/factor/parser/StackComment.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import java.io.IOException; public class StackComment extends FactorParsingDefinition @@ -39,10 +38,10 @@ public class StackComment extends FactorParsingDefinition /** * A new definition. */ - public StackComment(FactorWord word, Workspace workspace) + public StackComment(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/StringLiteral.java b/factor/parser/StringLiteral.java index 43efbb1c23..8d81bab100 100644 --- a/factor/parser/StringLiteral.java +++ b/factor/parser/StringLiteral.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import java.io.IOException; public class StringLiteral extends FactorParsingDefinition @@ -41,11 +40,10 @@ public class StringLiteral extends FactorParsingDefinition /** * A new definition. */ - public StringLiteral(FactorWord word, boolean escapes, - Workspace workspace) + public StringLiteral(FactorWord word, boolean escapes) throws Exception { - super(word,workspace); + super(word); this.escapes = escapes; } //}}} diff --git a/factor/parser/T.java b/factor/parser/T.java index abda61e9ec..2df155eb58 100644 --- a/factor/parser/T.java +++ b/factor/parser/T.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class T extends FactorParsingDefinition { @@ -38,10 +37,10 @@ public class T extends FactorParsingDefinition /** * A new definition. */ - public T(FactorWord word, Workspace workspace) + public T(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/Unreadable.java b/factor/parser/Unreadable.java index 494d623ff7..43529c4f7c 100644 --- a/factor/parser/Unreadable.java +++ b/factor/parser/Unreadable.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; import java.io.IOException; public class Unreadable extends FactorParsingDefinition @@ -39,10 +38,10 @@ public class Unreadable extends FactorParsingDefinition /** * A new definition. */ - public Unreadable(FactorWord word, Workspace workspace) + public Unreadable(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} public void eval(FactorInterpreter interp, FactorReader reader) diff --git a/factor/parser/Use.java b/factor/parser/Use.java index 4e4f0f49f0..049f79ea54 100644 --- a/factor/parser/Use.java +++ b/factor/parser/Use.java @@ -30,7 +30,6 @@ package factor.parser; import factor.*; -import factor.db.*; public class Use extends FactorParsingDefinition { @@ -38,10 +37,10 @@ public class Use extends FactorParsingDefinition /** * A new definition. */ - public Use(FactorWord word, Workspace workspace) + public Use(FactorWord word) throws Exception { - super(word,workspace); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/.Call.java.marks b/factor/primitives/.Call.java.marks index 2dab92d2e9..cc69ebb1ca 100644 --- a/factor/primitives/.Call.java.marks +++ b/factor/primitives/.Call.java.marks @@ -1 +1 @@ -!a;1592;1592 +!a;1572;1572 diff --git a/factor/primitives/.Define.java.marks b/factor/primitives/.Define.java.marks index 2f5f52635f..98f08f8ae2 100644 --- a/factor/primitives/.Define.java.marks +++ b/factor/primitives/.Define.java.marks @@ -1 +1 @@ -!a;1536;1536 +!a;1494;1494 diff --git a/factor/primitives/.JVarGetStatic.java.marks b/factor/primitives/.JVarGetStatic.java.marks index 2dab92d2e9..cc69ebb1ca 100644 --- a/factor/primitives/.JVarGetStatic.java.marks +++ b/factor/primitives/.JVarGetStatic.java.marks @@ -1 +1 @@ -!a;1592;1592 +!a;1572;1572 diff --git a/factor/primitives/.JVarSet.java.marks b/factor/primitives/.JVarSet.java.marks index 2dab92d2e9..cc69ebb1ca 100644 --- a/factor/primitives/.JVarSet.java.marks +++ b/factor/primitives/.JVarSet.java.marks @@ -1 +1 @@ -!a;1592;1592 +!a;1572;1572 diff --git a/factor/primitives/.JVarSetStatic.java.marks b/factor/primitives/.JVarSetStatic.java.marks index 2dab92d2e9..cc69ebb1ca 100644 --- a/factor/primitives/.JVarSetStatic.java.marks +++ b/factor/primitives/.JVarSetStatic.java.marks @@ -1 +1 @@ -!a;1592;1592 +!a;1572;1572 diff --git a/factor/primitives/Call.java b/factor/primitives/Call.java index dc0a08b99f..36f28779bb 100644 --- a/factor/primitives/Call.java +++ b/factor/primitives/Call.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.lang.reflect.*; import java.util.Map; @@ -42,20 +41,9 @@ public class Call extends FactorPrimitiveDefinition /** * A new definition. */ - public Call(FactorWord word, Workspace workspace) - throws Exception + public Call(FactorWord word) { - super(word,workspace); - } //}}} - - //{{{ Call constructor - /** - * A blank definition, about to be unpickled. - */ - public Call(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/Coerce.java b/factor/primitives/Coerce.java index 61304f9ccf..094787ffae 100644 --- a/factor/primitives/Coerce.java +++ b/factor/primitives/Coerce.java @@ -30,9 +30,7 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; -import java.util.Set; import org.objectweb.asm.*; public class Coerce extends FactorPrimitiveDefinition @@ -41,20 +39,10 @@ public class Coerce extends FactorPrimitiveDefinition /** * A new definition. */ - public Coerce(FactorWord word, Workspace workspace) + public Coerce(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ Coerce constructor - /** - * A blank definition, about to be unpickled. - */ - public Coerce(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/Define.java b/factor/primitives/Define.java index e795efb0fd..1a70770d89 100644 --- a/factor/primitives/Define.java +++ b/factor/primitives/Define.java @@ -30,9 +30,7 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; -import java.util.Map; public class Define extends FactorPrimitiveDefinition { @@ -40,20 +38,10 @@ public class Define extends FactorPrimitiveDefinition /** * A new definition. */ - public Define(FactorWord word, Workspace workspace) + public Define(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ Define constructor - /** - * A blank definition, about to be unpickled. - */ - public Define(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/Execute.java b/factor/primitives/Execute.java index 2e1dd1502f..d3b6ec8490 100644 --- a/factor/primitives/Execute.java +++ b/factor/primitives/Execute.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.lang.reflect.*; import java.util.Set; @@ -42,20 +41,10 @@ public class Execute extends FactorPrimitiveDefinition /** * A new definition. */ - public Execute(FactorWord word, Workspace workspace) + public Execute(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ Execute constructor - /** - * A blank definition, about to be unpickled. - */ - public Execute(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/Ifte.java b/factor/primitives/Ifte.java index 3b92a20a9a..1fa895d20d 100644 --- a/factor/primitives/Ifte.java +++ b/factor/primitives/Ifte.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import org.objectweb.asm.*; @@ -40,20 +39,10 @@ public class Ifte extends FactorPrimitiveDefinition /** * A new definition. */ - public Ifte(FactorWord word, Workspace workspace) + public Ifte(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ Ifte constructor - /** - * A blank definition, about to be unpickled. - */ - public Ifte(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/InterpreterGet.java b/factor/primitives/InterpreterGet.java index 874a4620ea..8deddd3159 100644 --- a/factor/primitives/InterpreterGet.java +++ b/factor/primitives/InterpreterGet.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.util.Set; import org.objectweb.asm.*; @@ -41,20 +40,10 @@ public class InterpreterGet extends FactorPrimitiveDefinition /** * A new definition. */ - public InterpreterGet(FactorWord word, Workspace workspace) + public InterpreterGet(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ InterpreterGet constructor - /** - * A blank definition, about to be unpickled. - */ - public InterpreterGet(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/JInvoke.java b/factor/primitives/JInvoke.java index 449bedeaa9..1f94b247d7 100644 --- a/factor/primitives/JInvoke.java +++ b/factor/primitives/JInvoke.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.lang.reflect.*; import java.util.Map; @@ -44,24 +43,13 @@ public class JInvoke extends FactorPrimitiveDefinition /** * A new definition. */ - public JInvoke(FactorWord word, Workspace workspace, - boolean staticMethod) + public JInvoke(FactorWord word, boolean staticMethod) throws Exception { - super(word,workspace); + super(word); this.staticMethod = staticMethod; } //}}} - //{{{ JInvoke constructor - /** - * A blank definition, about to be unpickled. - */ - public JInvoke(Workspace workspace, long id) - throws Exception - { - super(workspace,id); - } //}}} - //{{{ checkStatic() method private void checkStatic(Method method) throws FactorRuntimeException { diff --git a/factor/primitives/JNew.java b/factor/primitives/JNew.java index 5216843310..29a767042b 100644 --- a/factor/primitives/JNew.java +++ b/factor/primitives/JNew.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.lang.reflect.*; import java.util.Map; @@ -42,20 +41,10 @@ public class JNew extends FactorPrimitiveDefinition /** * A new definition. */ - public JNew(FactorWord word, Workspace workspace) + public JNew(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ JNew constructor - /** - * A blank definition, about to be unpickled. - */ - public JNew(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/JVarGet.java b/factor/primitives/JVarGet.java index 74f13be1ea..a3e54d911e 100644 --- a/factor/primitives/JVarGet.java +++ b/factor/primitives/JVarGet.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.lang.reflect.*; import java.util.Map; @@ -42,20 +41,10 @@ public class JVarGet extends FactorPrimitiveDefinition /** * A new definition. */ - public JVarGet(FactorWord word, Workspace workspace) + public JVarGet(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ JVarGet constructor - /** - * A blank definition, about to be unpickled. - */ - public JVarGet(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/JVarGetStatic.java b/factor/primitives/JVarGetStatic.java index 404a264c48..70d3f5946c 100644 --- a/factor/primitives/JVarGetStatic.java +++ b/factor/primitives/JVarGetStatic.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.lang.reflect.*; import java.util.Map; @@ -42,20 +41,10 @@ public class JVarGetStatic extends FactorPrimitiveDefinition /** * A new definition. */ - public JVarGetStatic(FactorWord word, Workspace workspace) + public JVarGetStatic(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ JVarGetStatic constructor - /** - * A blank definition, about to be unpickled. - */ - public JVarGetStatic(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/JVarSet.java b/factor/primitives/JVarSet.java index da2513bfc5..e2b1bcb3f9 100644 --- a/factor/primitives/JVarSet.java +++ b/factor/primitives/JVarSet.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.lang.reflect.*; import java.util.Map; @@ -42,20 +41,10 @@ public class JVarSet extends FactorPrimitiveDefinition /** * A new definition. */ - public JVarSet(FactorWord word, Workspace workspace) + public JVarSet(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ JVarSet constructor - /** - * A blank definition, about to be unpickled. - */ - public JVarSet(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/JVarSetStatic.java b/factor/primitives/JVarSetStatic.java index 76f0a33b9b..170d8ca2f3 100644 --- a/factor/primitives/JVarSetStatic.java +++ b/factor/primitives/JVarSetStatic.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.lang.reflect.*; import java.util.Map; @@ -42,20 +41,10 @@ public class JVarSetStatic extends FactorPrimitiveDefinition /** * A new definition. */ - public JVarSetStatic(FactorWord word, Workspace workspace) + public JVarSetStatic(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ JVarSetStatic constructor - /** - * A blank definition, about to be unpickled. - */ - public JVarSetStatic(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/Restack.java b/factor/primitives/Restack.java index e199faccb6..cff8e0d3fa 100644 --- a/factor/primitives/Restack.java +++ b/factor/primitives/Restack.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.util.Set; @@ -40,20 +39,10 @@ public class Restack extends FactorPrimitiveDefinition /** * A new definition. */ - public Restack(FactorWord word, Workspace workspace) + public Restack(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ Restack constructor - /** - * A blank definition, about to be unpickled. - */ - public Restack(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/factor/primitives/Unstack.java b/factor/primitives/Unstack.java index 129224e644..33f066f221 100644 --- a/factor/primitives/Unstack.java +++ b/factor/primitives/Unstack.java @@ -30,7 +30,6 @@ package factor.primitives; import factor.compiler.*; -import factor.db.*; import factor.*; import java.util.Set; @@ -40,20 +39,10 @@ public class Unstack extends FactorPrimitiveDefinition /** * A new definition. */ - public Unstack(FactorWord word, Workspace workspace) + public Unstack(FactorWord word) throws Exception { - super(word,workspace); - } //}}} - - //{{{ Unstack constructor - /** - * A blank definition, about to be unpickled. - */ - public Unstack(Workspace workspace, long id) - throws Exception - { - super(workspace,id); + super(word); } //}}} //{{{ eval() method diff --git a/library/debugger.factor b/library/debugger.factor index 270a6891a9..99ab582591 100644 --- a/library/debugger.factor +++ b/library/debugger.factor @@ -29,9 +29,9 @@ IN: errors USE: combinators USE: continuations USE: kernel -USE: inspector USE: logic USE: namespaces +USE: prettyprint USE: stack USE: stdio USE: strings @@ -65,14 +65,7 @@ USE: unparser suspend ; -: ?describe-stack ( stack -- ) - dup [ - describe-stack - ] [ - drop "No stack" print - ] ifte ; - -: :s ( -- ) "error-datastack" get ?describe-stack ; -: :r ( -- ) "error-callstack" get ?describe-stack ; -: :n ( -- ) "error-namestack" get ?describe-stack ; -: :c ( -- ) "error-catchstack" get ?describe-stack ; +: :s ( -- ) "error-datastack" get prettyprint ; +: :r ( -- ) "error-callstack" get prettyprint ; +: :n ( -- ) "error-namestack" get prettyprint ; +: :c ( -- ) "error-catchstack" get prettyprint ; diff --git a/library/errors.factor b/library/errors.factor index 3743ab2220..0fb9b813b7 100644 --- a/library/errors.factor +++ b/library/errors.factor @@ -36,18 +36,11 @@ USE: stack USE: strings USE: vectors -: >c ( catch -- ) - #! Push a catch block on the catchstack. Use the catch word - #! instead of invoking this word directly. - catchstack* vector-push ; - -: c> ( catch -- ) - #! Pop a catch block from the catchstack. Use the catch word - #! instead of invoking this word directly. - catchstack* vector-pop ; +: >c ( catch -- ) catchstack* vector-push ; +: c> ( catch -- ) catchstack* vector-pop ; : save-error ( error -- ) - #! Save the stacks for most-mortem inspection after an + #! Save the stacks for post-mortem inspection after an #! error. global [ "error" set @@ -58,18 +51,14 @@ USE: vectors ] bind ; : catch ( try catch -- ) - #! Call the try quotation, restore the datastack to its - #! state before the try quotation, push the error (or f if - #! no error occurred) and call the catch quotation. - [ >c >r call c> drop f r> f ] callcc1 - ( try catch error ) rot drop swap ( error catch ) call ; + #! Call the try quotation. If an error occurs restore the + #! datastack, push the error, and call the catch block. + #! If no error occurs, push f and call the catch block. + [ >c >r call c> drop f r> f ] callcc1 rot drop swap call ; : rethrow ( error -- ) #! Use rethrow when passing an error on from a catch block. #! For convinience, this word is a no-op if error is f. [ c> call ] when* ; -: throw ( error -- ) - #! Throw an error. If no catch handlers are installed, the - #! default-error-handler is called. - dup save-error rethrow ; +: throw ( error -- ) dup save-error rethrow ; diff --git a/library/httpd/default-responders.factor b/library/httpd/default-responders.factor index d12fb25e2a..e5f47398ea 100644 --- a/library/httpd/default-responders.factor +++ b/library/httpd/default-responders.factor @@ -37,7 +37,7 @@ USE: wiki-responder : default-responders ( -- ) #! Remove all existing responders, and create a blank #! responder table. -