removed factor db
parent
cb758942aa
commit
88e3ea7ab4
|
@ -4,7 +4,6 @@
|
||||||
- minimal use/in for parse-stream
|
- minimal use/in for parse-stream
|
||||||
- prettyprint-1
|
- prettyprint-1
|
||||||
- {...} vectors
|
- {...} vectors
|
||||||
- better .s
|
|
||||||
- parsing should be parsing
|
- parsing should be parsing
|
||||||
- telnetd: listening on a socket
|
- telnetd: listening on a socket
|
||||||
- vocab inspecting ==> worddef>list, assumes . on a list works
|
- vocab inspecting ==> worddef>list, assumes . on a list works
|
||||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
!a;7528;7528
|
!a;6964;6964
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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
|
//{{{ elementsToString() method
|
||||||
/**
|
/**
|
||||||
* Returns a whitespace separated string of the unparseObject() of each
|
* Returns a whitespace separated string of the unparseObject() of each
|
||||||
* item.
|
* item.
|
||||||
*/
|
*/
|
||||||
public String elementsToString()
|
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();
|
StringBuffer buf = new StringBuffer();
|
||||||
Cons iter = this;
|
Cons iter = this;
|
||||||
while(iter != null)
|
while(iter != null)
|
||||||
{
|
{
|
||||||
buf.append(dbUnparse ?
|
buf.append(FactorReader.unparseObject(iter.car));
|
||||||
FactorReader.unparseDBObject(iter.car)
|
|
||||||
: FactorReader.unparseObject(iter.car));
|
|
||||||
if(iter.cdr instanceof Cons)
|
if(iter.cdr instanceof Cons)
|
||||||
{
|
{
|
||||||
buf.append(' ');
|
buf.append(' ');
|
||||||
|
@ -204,9 +183,7 @@ public class Cons implements PublicCloneable, FactorExternalizable
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf.append(" | ");
|
buf.append(" | ");
|
||||||
buf.append(dbUnparse ?
|
buf.append(FactorReader.unparseObject(iter.cdr));
|
||||||
FactorReader.unparseDBObject(iter.cdr)
|
|
||||||
: FactorReader.unparseObject(iter.cdr));
|
|
||||||
iter = null;
|
iter = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +197,7 @@ public class Cons implements PublicCloneable, FactorExternalizable
|
||||||
*/
|
*/
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "[ " + elementsToString(false) + " ]";
|
return "[ " + elementsToString() + " ]";
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ toArray() method
|
//{{{ toArray() method
|
||||||
|
|
|
@ -30,10 +30,10 @@
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factor is a stack-based language.
|
* A growable array.
|
||||||
* @author Slava Pestov
|
* @author Slava Pestov
|
||||||
*/
|
*/
|
||||||
public class FactorArray implements PublicCloneable
|
public class FactorArray implements FactorExternalizable, PublicCloneable
|
||||||
{
|
{
|
||||||
public Object[] stack;
|
public Object[] stack;
|
||||||
public int top;
|
public int top;
|
||||||
|
@ -159,6 +159,22 @@ public class FactorArray implements PublicCloneable
|
||||||
return stack.length;
|
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
|
//{{{ toList() method
|
||||||
public Cons toList()
|
public Cons toList()
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.Workspace;
|
|
||||||
import factor.db.PersistenceException;
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -52,29 +50,16 @@ public class FactorCompoundDefinition extends FactorWordDefinition
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public FactorCompoundDefinition(FactorWord word, Cons definition,
|
public FactorCompoundDefinition(FactorWord word, Cons definition,
|
||||||
FactorInterpreter interp) throws PersistenceException
|
FactorInterpreter interp)
|
||||||
{
|
{
|
||||||
super(word,interp.workspace);
|
super(word);
|
||||||
fromList(definition,interp);
|
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
|
//{{{ eval() method
|
||||||
public void eval(FactorInterpreter interp)
|
public void eval(FactorInterpreter interp)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
lazyInit(interp);
|
|
||||||
interp.call(endOfDocs);
|
interp.call(endOfDocs);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
@ -82,7 +67,6 @@ public class FactorCompoundDefinition extends FactorWordDefinition
|
||||||
public void getStackEffect(RecursiveState recursiveCheck,
|
public void getStackEffect(RecursiveState recursiveCheck,
|
||||||
FactorCompiler compiler) throws Exception
|
FactorCompiler compiler) throws Exception
|
||||||
{
|
{
|
||||||
lazyInit(compiler.interp);
|
|
||||||
RecursiveForm rec = recursiveCheck.get(word);
|
RecursiveForm rec = recursiveCheck.get(word);
|
||||||
if(rec.active)
|
if(rec.active)
|
||||||
{
|
{
|
||||||
|
@ -111,10 +95,8 @@ public class FactorCompoundDefinition extends FactorWordDefinition
|
||||||
FactorWordDefinition compile(FactorInterpreter interp,
|
FactorWordDefinition compile(FactorInterpreter interp,
|
||||||
RecursiveState recursiveCheck) throws Exception
|
RecursiveState recursiveCheck) throws Exception
|
||||||
{
|
{
|
||||||
lazyInit(interp);
|
|
||||||
// Each word has its own class loader
|
// Each word has its own class loader
|
||||||
FactorClassLoader loader = new FactorClassLoader(
|
FactorClassLoader loader = new FactorClassLoader();
|
||||||
interp.workspace);
|
|
||||||
|
|
||||||
StackEffect effect = getStackEffect(interp);
|
StackEffect effect = getStackEffect(interp);
|
||||||
|
|
||||||
|
|
|
@ -29,20 +29,13 @@
|
||||||
|
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
import factor.db.*;
|
|
||||||
import factor.parser.*;
|
import factor.parser.*;
|
||||||
import factor.primitives.*;
|
import factor.primitives.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
public class FactorInterpreter implements FactorObject, Runnable
|
public class FactorInterpreter implements FactorObject, Runnable
|
||||||
{
|
{
|
||||||
public static final String VERSION = "0.60.6";
|
public static final String VERSION = "0.60.8";
|
||||||
|
|
||||||
// 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";
|
|
||||||
|
|
||||||
// command line arguments are stored here.
|
// command line arguments are stored here.
|
||||||
public Cons args;
|
public Cons args;
|
||||||
|
@ -52,8 +45,9 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
public Throwable error;
|
public Throwable error;
|
||||||
public boolean dump = false;
|
public boolean dump = false;
|
||||||
public boolean verboseCompile = false;
|
public boolean verboseCompile = false;
|
||||||
public boolean firstTime = false;
|
|
||||||
public boolean mini = false;
|
public boolean mini = false;
|
||||||
|
// if this is false and an error occurs, bail out.
|
||||||
|
public boolean startupDone = false;
|
||||||
|
|
||||||
public Cons callframe;
|
public Cons callframe;
|
||||||
public FactorArray callstack = new FactorArray();
|
public FactorArray callstack = new FactorArray();
|
||||||
|
@ -87,11 +81,6 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
*/
|
*/
|
||||||
public FactorWord last;
|
public FactorWord last;
|
||||||
|
|
||||||
/**
|
|
||||||
* Persistent store, maybe null.
|
|
||||||
*/
|
|
||||||
public Workspace workspace;
|
|
||||||
|
|
||||||
public FactorNamespace global;
|
public FactorNamespace global;
|
||||||
|
|
||||||
private FactorNamespace interpNamespace;
|
private FactorNamespace interpNamespace;
|
||||||
|
@ -104,8 +93,6 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
FactorInterpreter interp = new FactorInterpreter();
|
FactorInterpreter interp = new FactorInterpreter();
|
||||||
interp.init(args,null);
|
interp.init(args,null);
|
||||||
interp.run();
|
interp.run();
|
||||||
if(interp.workspace != null)
|
|
||||||
interp.workspace.close();
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ init() method
|
//{{{ init() method
|
||||||
|
@ -115,7 +102,6 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
this.interactive = interp.interactive;
|
this.interactive = interp.interactive;
|
||||||
this.dump = interp.dump;
|
this.dump = interp.dump;
|
||||||
this.verboseCompile = interp.verboseCompile;
|
this.verboseCompile = interp.verboseCompile;
|
||||||
this.firstTime = firstTime;
|
|
||||||
this.callframe = interp.callframe;
|
this.callframe = interp.callframe;
|
||||||
this.callstack = (FactorArray)interp.callstack.clone();
|
this.callstack = (FactorArray)interp.callstack.clone();
|
||||||
this.datastack = (FactorArray)interp.datastack.clone();
|
this.datastack = (FactorArray)interp.datastack.clone();
|
||||||
|
@ -126,7 +112,6 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
this.in = interp.in;
|
this.in = interp.in;
|
||||||
this.builtins = interp.builtins;
|
this.builtins = interp.builtins;
|
||||||
this.last = interp.last;
|
this.last = interp.last;
|
||||||
this.workspace = interp.workspace;
|
|
||||||
this.global = interp.global;
|
this.global = interp.global;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
@ -136,39 +121,8 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
for(int i = 0; i < args.length; i++)
|
for(int i = 0; i < args.length; i++)
|
||||||
{
|
{
|
||||||
String arg = args[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
|
// this switch forces minimal libraries to be loaded
|
||||||
else if(arg.equals("-no-mini"))
|
if(arg.equals("-no-mini"))
|
||||||
{
|
{
|
||||||
mini = false;
|
mini = false;
|
||||||
args[i] = null;
|
args[i] = null;
|
||||||
|
@ -182,7 +136,7 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
|
|
||||||
this.args = Cons.fromArray(args);
|
this.args = Cons.fromArray(args);
|
||||||
|
|
||||||
vocabularies = new Table(workspace);
|
vocabularies = new FactorNamespace();
|
||||||
initBuiltinDictionary();
|
initBuiltinDictionary();
|
||||||
initNamespace(root);
|
initNamespace(root);
|
||||||
topLevel();
|
topLevel();
|
||||||
|
@ -190,35 +144,10 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
runBootstrap();
|
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
|
//{{{ initBuiltinDictionary() method
|
||||||
private void initBuiltinDictionary() throws Exception
|
private void initBuiltinDictionary() throws Exception
|
||||||
{
|
{
|
||||||
builtins = new Table(null);
|
builtins = new FactorNamespace();
|
||||||
vocabularies.setVariable("builtins",builtins);
|
vocabularies.setVariable("builtins",builtins);
|
||||||
|
|
||||||
in = "builtins";
|
in = "builtins";
|
||||||
|
@ -226,129 +155,123 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
|
|
||||||
// parsing words
|
// parsing words
|
||||||
FactorWord lineComment = define("builtins","!");
|
FactorWord lineComment = define("builtins","!");
|
||||||
lineComment.parsing = new LineComment(lineComment,false,null);
|
lineComment.parsing = new LineComment(lineComment,false);
|
||||||
FactorWord stackComment = define("builtins","(");
|
FactorWord stackComment = define("builtins","(");
|
||||||
stackComment.parsing = new StackComment(stackComment,null);
|
stackComment.parsing = new StackComment(stackComment);
|
||||||
FactorWord str = define("builtins","\"");
|
FactorWord str = define("builtins","\"");
|
||||||
str.parsing = new StringLiteral(str,true,null);
|
str.parsing = new StringLiteral(str,true);
|
||||||
FactorWord t = define("builtins","t");
|
FactorWord t = define("builtins","t");
|
||||||
t.parsing = new T(t,null);
|
t.parsing = new T(t);
|
||||||
FactorWord f = define("builtins","f");
|
FactorWord f = define("builtins","f");
|
||||||
f.parsing = new F(f,null);
|
f.parsing = new F(f);
|
||||||
FactorWord bra = define("builtins","[");
|
FactorWord bra = define("builtins","[");
|
||||||
bra.parsing = new Bra(bra,null);
|
bra.parsing = new Bra(bra);
|
||||||
FactorWord ket = define("builtins","]");
|
FactorWord ket = define("builtins","]");
|
||||||
ket.parsing = new Ket(bra,ket,null);
|
ket.parsing = new Ket(bra,ket);
|
||||||
FactorWord bar = define("builtins","|");
|
FactorWord bar = define("builtins","|");
|
||||||
bar.parsing = new Bar(bar,null);
|
bar.parsing = new Bar(bar);
|
||||||
FactorWord def = define("builtins",":");
|
FactorWord def = define("builtins",":");
|
||||||
def.parsing = new Def(def,null);
|
def.parsing = new Def(def);
|
||||||
def.getNamespace().setVariable("doc-comments",Boolean.TRUE);
|
def.getNamespace().setVariable("doc-comments",Boolean.TRUE);
|
||||||
FactorWord ine = define("builtins",";");
|
FactorWord ine = define("builtins",";");
|
||||||
ine.parsing = new Ine(def,ine,null);
|
ine.parsing = new Ine(def,ine);
|
||||||
FactorWord shuffle = define("builtins","~<<");
|
FactorWord shuffle = define("builtins","~<<");
|
||||||
shuffle.parsing = new Shuffle(shuffle,">>~",null);
|
shuffle.parsing = new Shuffle(shuffle,">>~");
|
||||||
|
|
||||||
FactorWord noParsing = define("builtins","POSTPONE:");
|
FactorWord noParsing = define("builtins","POSTPONE:");
|
||||||
noParsing.parsing = new NoParsing(noParsing,null);
|
noParsing.parsing = new NoParsing(noParsing);
|
||||||
|
|
||||||
// #X
|
// #X
|
||||||
FactorWord dispatch = define("builtins","#");
|
FactorWord dispatch = define("builtins","#");
|
||||||
dispatch.parsing = new Dispatch(dispatch,null);
|
dispatch.parsing = new Dispatch(dispatch);
|
||||||
FactorWord getPersistentObject = define("builtins","#O");
|
|
||||||
getPersistentObject.parsing = new GetPersistentObject(
|
|
||||||
getPersistentObject,null);
|
|
||||||
FactorWord ch = define("builtins","#\\");
|
FactorWord ch = define("builtins","#\\");
|
||||||
ch.parsing = new CharLiteral(ch,null);
|
ch.parsing = new CharLiteral(ch);
|
||||||
FactorWord raw = define("builtins","#\"");
|
FactorWord raw = define("builtins","#\"");
|
||||||
raw.parsing = new StringLiteral(raw,false,null);
|
raw.parsing = new StringLiteral(raw,false);
|
||||||
FactorWord complex = define("builtins","#{");
|
FactorWord complex = define("builtins","#{");
|
||||||
complex.parsing = new ComplexLiteral(complex,"}",null);
|
complex.parsing = new ComplexLiteral(complex,"}");
|
||||||
FactorWord docComment = define("builtins","#!");
|
FactorWord docComment = define("builtins","#!");
|
||||||
docComment.parsing = new LineComment(docComment,true,null);
|
docComment.parsing = new LineComment(docComment,true);
|
||||||
FactorWord unreadable = define("builtins","#<");
|
FactorWord unreadable = define("builtins","#<");
|
||||||
unreadable.parsing = new Unreadable(unreadable,null);
|
unreadable.parsing = new Unreadable(unreadable);
|
||||||
|
|
||||||
// #: is not handled with a special dispatch. instead, when
|
// #: is not handled with a special dispatch. instead, when
|
||||||
// a word starting with #: is passed to intern(), it creates
|
// a word starting with #: is passed to intern(), it creates
|
||||||
// a new symbol
|
// a new symbol
|
||||||
FactorWord passthru = define("builtins","#:");
|
FactorWord passthru = define("builtins","#:");
|
||||||
passthru.parsing = new PassThrough(passthru,null);
|
passthru.parsing = new PassThrough(passthru);
|
||||||
|
|
||||||
// vocabulary parsing words
|
// vocabulary parsing words
|
||||||
FactorWord defer = define("builtins","DEFER:");
|
FactorWord defer = define("builtins","DEFER:");
|
||||||
defer.parsing = new Defer(defer,null);
|
defer.parsing = new Defer(defer);
|
||||||
FactorWord in = define("builtins","IN:");
|
FactorWord in = define("builtins","IN:");
|
||||||
in.parsing = new In(in,null);
|
in.parsing = new In(in);
|
||||||
FactorWord use = define("builtins","USE:");
|
FactorWord use = define("builtins","USE:");
|
||||||
use.parsing = new Use(use,null);
|
use.parsing = new Use(use);
|
||||||
|
|
||||||
FactorWord interpreterGet = define("builtins","interpreter");
|
FactorWord interpreterGet = define("builtins","interpreter");
|
||||||
interpreterGet.def = new InterpreterGet(interpreterGet,null);
|
interpreterGet.def = new InterpreterGet(interpreterGet);
|
||||||
interpreterGet.inline = true;
|
interpreterGet.inline = true;
|
||||||
|
|
||||||
// reading numbers with another base
|
// reading numbers with another base
|
||||||
FactorWord bin = define("builtins","BIN:");
|
FactorWord bin = define("builtins","BIN:");
|
||||||
bin.parsing = new Base(defer,null,2);
|
bin.parsing = new Base(bin,2);
|
||||||
FactorWord oct = define("builtins","OCT:");
|
FactorWord oct = define("builtins","OCT:");
|
||||||
oct.parsing = new Base(defer,null,8);
|
oct.parsing = new Base(oct,8);
|
||||||
FactorWord hex = define("builtins","HEX:");
|
FactorWord hex = define("builtins","HEX:");
|
||||||
hex.parsing = new Base(defer,null,16);
|
hex.parsing = new Base(hex,16);
|
||||||
|
|
||||||
// primitives used by 'expand' and 'map'
|
// primitives used by 'expand' and 'map'
|
||||||
FactorWord restack = define("builtins","restack");
|
FactorWord restack = define("builtins","restack");
|
||||||
restack.def = new Restack(restack,null);
|
restack.def = new Restack(restack);
|
||||||
FactorWord unstack = define("builtins","unstack");
|
FactorWord unstack = define("builtins","unstack");
|
||||||
unstack.def = new Unstack(unstack,null);
|
unstack.def = new Unstack(unstack);
|
||||||
|
|
||||||
// reflection primitives
|
// reflection primitives
|
||||||
FactorWord jinvoke = define("builtins","jinvoke");
|
FactorWord jinvoke = define("builtins","jinvoke");
|
||||||
jinvoke.def = new JInvoke(jinvoke,null,false);
|
jinvoke.def = new JInvoke(jinvoke,false);
|
||||||
jinvoke.inline = true;
|
jinvoke.inline = true;
|
||||||
FactorWord jinvokeStatic = define("builtins","jinvoke-static");
|
FactorWord jinvokeStatic = define("builtins","jinvoke-static");
|
||||||
jinvokeStatic.def = new JInvoke(jinvokeStatic,null,true);
|
jinvokeStatic.def = new JInvoke(jinvokeStatic,true);
|
||||||
jinvokeStatic.inline = true;
|
jinvokeStatic.inline = true;
|
||||||
FactorWord jnew = define("builtins","jnew");
|
FactorWord jnew = define("builtins","jnew");
|
||||||
jnew.def = new JNew(jnew,null);
|
jnew.def = new JNew(jnew);
|
||||||
jnew.inline = true;
|
jnew.inline = true;
|
||||||
FactorWord jvarGet = define("builtins","jvar-get");
|
FactorWord jvarGet = define("builtins","jvar-get");
|
||||||
jvarGet.def = new JVarGet(jvarGet,null);
|
jvarGet.def = new JVarGet(jvarGet);
|
||||||
jvarGet.inline = true;
|
jvarGet.inline = true;
|
||||||
FactorWord jvarGetStatic = define("builtins","jvar-static-get");
|
FactorWord jvarGetStatic = define("builtins","jvar-static-get");
|
||||||
jvarGetStatic.def = new JVarGetStatic(jvarGetStatic,null);
|
jvarGetStatic.def = new JVarGetStatic(jvarGetStatic);
|
||||||
jvarGetStatic.inline = true;
|
jvarGetStatic.inline = true;
|
||||||
FactorWord jvarSet = define("builtins","jvar-set");
|
FactorWord jvarSet = define("builtins","jvar-set");
|
||||||
jvarSet.def = new JVarSet(jvarSet,null);
|
jvarSet.def = new JVarSet(jvarSet);
|
||||||
jvarSet.inline = true;
|
jvarSet.inline = true;
|
||||||
FactorWord jvarSetStatic = define("builtins","jvar-static-set");
|
FactorWord jvarSetStatic = define("builtins","jvar-static-set");
|
||||||
jvarSetStatic.def = new JVarSetStatic(jvarSetStatic,null);
|
jvarSetStatic.def = new JVarSetStatic(jvarSetStatic);
|
||||||
jvarSetStatic.inline = true;
|
jvarSetStatic.inline = true;
|
||||||
FactorWord coerce = define("builtins","coerce");
|
FactorWord coerce = define("builtins","coerce");
|
||||||
coerce.def = new Coerce(coerce,null);
|
coerce.def = new Coerce(coerce);
|
||||||
coerce.inline = true;
|
coerce.inline = true;
|
||||||
|
|
||||||
// definition
|
// definition
|
||||||
FactorWord define = define("builtins","define");
|
FactorWord define = define("builtins","define");
|
||||||
define.def = new Define(define,null);
|
define.def = new Define(define);
|
||||||
|
|
||||||
// combinators
|
// combinators
|
||||||
FactorWord execute = define("builtins","execute");
|
FactorWord execute = define("builtins","execute");
|
||||||
execute.def = new Execute(execute,null);
|
execute.def = new Execute(execute);
|
||||||
FactorWord call = define("builtins","call");
|
FactorWord call = define("builtins","call");
|
||||||
call.def = new Call(call,null);
|
call.def = new Call(call);
|
||||||
call.inline = true;
|
call.inline = true;
|
||||||
FactorWord ifte = define("builtins","ifte");
|
FactorWord ifte = define("builtins","ifte");
|
||||||
ifte.def = new Ifte(ifte,null);
|
ifte.def = new Ifte(ifte);
|
||||||
ifte.inline = true;
|
ifte.inline = true;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ initNamespace() method
|
//{{{ initNamespace() method
|
||||||
private void initNamespace(Object root) throws Exception
|
private void initNamespace(Object root) throws Exception
|
||||||
{
|
{
|
||||||
if(workspace == null)
|
|
||||||
global = new FactorNamespace(null,root);
|
global = new FactorNamespace(null,root);
|
||||||
else
|
|
||||||
global = workspace.getRoot();
|
|
||||||
|
|
||||||
global.setVariable("interpreter",this);
|
global.setVariable("interpreter",this);
|
||||||
|
|
||||||
|
@ -357,37 +280,14 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
getClass().getField("verboseCompile"),
|
getClass().getField("verboseCompile"),
|
||||||
this));
|
this));
|
||||||
|
|
||||||
global.setVariable("global",
|
global.setVariable("startup-done",
|
||||||
new FactorNamespace.VarBinding(
|
new FactorNamespace.VarBinding(
|
||||||
getClass().getField("global"),
|
getClass().getField("startupDone"),
|
||||||
this));
|
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 = {
|
String[] boundFields = {
|
||||||
|
"global",
|
||||||
|
"vocabularies",
|
||||||
"args",
|
"args",
|
||||||
"dump",
|
"dump",
|
||||||
"interactive",
|
"interactive",
|
||||||
|
@ -420,11 +320,6 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
//{{{ runBootstrap() method
|
//{{{ runBootstrap() method
|
||||||
private void runBootstrap() throws Exception
|
private void runBootstrap() throws Exception
|
||||||
{
|
{
|
||||||
if(workspace == null || workspace.isFirstTime()
|
|
||||||
|| firstTime)
|
|
||||||
{
|
|
||||||
if(workspace != null)
|
|
||||||
workspace.setFirstTime(false);
|
|
||||||
String initFile = "/library/platform/jvm/boot.factor";
|
String initFile = "/library/platform/jvm/boot.factor";
|
||||||
FactorReader parser = new FactorReader(
|
FactorReader parser = new FactorReader(
|
||||||
initFile,
|
initFile,
|
||||||
|
@ -435,9 +330,6 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
this);
|
this);
|
||||||
|
|
||||||
call(parser.parse());
|
call(parser.parse());
|
||||||
}
|
|
||||||
else
|
|
||||||
eval(searchVocabulary(INIT_VOCAB,"boot"));
|
|
||||||
|
|
||||||
run();
|
run();
|
||||||
} //}}}
|
} //}}}
|
||||||
|
@ -479,17 +371,27 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
private boolean handleError(Throwable e)
|
private boolean handleError(Throwable e)
|
||||||
{
|
{
|
||||||
error = FactorJava.unwrapException(e);
|
error = FactorJava.unwrapException(e);
|
||||||
|
if(!startupDone)
|
||||||
|
{
|
||||||
|
error.printStackTrace();
|
||||||
|
topLevel();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
datastack.push(error);
|
datastack.push(error);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
eval(searchVocabulary(ERRORS_VOCAB,"throw"));
|
FactorWord throwWord = searchVocabulary(
|
||||||
|
"errors","throw");
|
||||||
|
if(throwWord == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
eval(throwWord);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch(Throwable e2)
|
catch(Throwable e2)
|
||||||
{
|
{
|
||||||
System.err.println("Exception when calling throw:");
|
System.err.println("Exception when calling throw:");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
||||||
topLevel();
|
topLevel();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -609,7 +511,7 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
Object value = vocabularies.getVariable(name);
|
Object value = vocabularies.getVariable(name);
|
||||||
if(value == null)
|
if(value == null)
|
||||||
{
|
{
|
||||||
value = new Table(workspace);
|
value = new FactorNamespace();
|
||||||
vocabularies.setVariable(name,value);
|
vocabularies.setVariable(name,value);
|
||||||
}
|
}
|
||||||
} //}}}
|
} //}}}
|
||||||
|
@ -680,7 +582,7 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
FactorNamespace v = getVocabulary(vocabulary);
|
FactorNamespace v = getVocabulary(vocabulary);
|
||||||
if(v == null)
|
if(v == null)
|
||||||
{
|
{
|
||||||
v = new Table(workspace);
|
v = new FactorNamespace();
|
||||||
vocabularies.setVariable(vocabulary,v);
|
vocabularies.setVariable(vocabulary,v);
|
||||||
}
|
}
|
||||||
Object value = v.getVariable(name);
|
Object value = v.getVariable(name);
|
||||||
|
@ -688,18 +590,9 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
return (FactorWord)value;
|
return (FactorWord)value;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Workspace workspace;
|
|
||||||
if(v instanceof PersistentObject)
|
|
||||||
{
|
|
||||||
workspace = ((PersistentObject)v)
|
|
||||||
.getWorkspace();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
workspace = null;
|
|
||||||
|
|
||||||
// save to same workspace as vocabulary,
|
// save to same workspace as vocabulary,
|
||||||
// or no workspace if vocabulary is builtins
|
// or no workspace if vocabulary is builtins
|
||||||
FactorWord word = new FactorWord(workspace,
|
FactorWord word = new FactorWord(
|
||||||
vocabulary,name,null);
|
vocabulary,name,null);
|
||||||
v.setVariable(name,word);
|
v.setVariable(name,word);
|
||||||
return word;
|
return word;
|
||||||
|
@ -724,8 +617,11 @@ public class FactorInterpreter implements FactorObject, Runnable
|
||||||
namestack.push(global);
|
namestack.push(global);
|
||||||
catchstack.top = 0;
|
catchstack.top = 0;
|
||||||
// DEFER: the word
|
// DEFER: the word
|
||||||
define(ERRORS_VOCAB,"default-error-handler");
|
define("kernel","exit*");
|
||||||
catchstack.push(new Cons(searchVocabulary(ERRORS_VOCAB,
|
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));
|
"default-error-handler"),null));
|
||||||
callframe = null;
|
callframe = null;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
|
@ -29,13 +29,12 @@
|
||||||
|
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A parsing word definition.
|
* A parsing word definition.
|
||||||
*/
|
*/
|
||||||
public abstract class FactorParsingDefinition extends SimplePersistentObject
|
public abstract class FactorParsingDefinition
|
||||||
{
|
{
|
||||||
public static final String ENCODING = "UTF8";
|
public static final String ENCODING = "UTF8";
|
||||||
|
|
||||||
|
@ -45,24 +44,10 @@ public abstract class FactorParsingDefinition extends SimplePersistentObject
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public FactorParsingDefinition(FactorWord word, Workspace workspace)
|
public FactorParsingDefinition(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
this(workspace,workspace == null
|
|
||||||
? 0L : workspace.nextID());
|
|
||||||
this.word = word;
|
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)
|
public abstract void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,22 +41,9 @@ public abstract class FactorPrimitiveDefinition extends FactorWordDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public FactorPrimitiveDefinition(FactorWord word, Workspace workspace)
|
public FactorPrimitiveDefinition(FactorWord word)
|
||||||
throws Exception
|
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
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);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ fromList() method
|
//{{{ fromList() method
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
|
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
import factor.db.PersistentIgnore;
|
|
||||||
import factor.db.PersistentObject;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
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
|
//{{{ unparseObject() method
|
||||||
public static String unparseObject(Object obj)
|
public static String unparseObject(Object obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.Workspace;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
|
@ -59,21 +58,12 @@ public class FactorShuffleDefinition extends FactorWordDefinition
|
||||||
private int shuffleRstart;
|
private int shuffleRstart;
|
||||||
private int shuffleRlength;
|
private int shuffleRlength;
|
||||||
|
|
||||||
//{{{ FactorShuffleDefinition constructor
|
|
||||||
public FactorShuffleDefinition(Workspace workspace, long id)
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ FactorShuffleDefinition constructor
|
//{{{ FactorShuffleDefinition constructor
|
||||||
public FactorShuffleDefinition(FactorWord word, Cons definition,
|
public FactorShuffleDefinition(FactorWord word, Cons definition,
|
||||||
FactorInterpreter interp) throws FactorException
|
FactorInterpreter interp) throws FactorException
|
||||||
{
|
{
|
||||||
super(word,interp.workspace);
|
super(word);
|
||||||
fromList(definition,interp);
|
fromList(definition,interp);
|
||||||
|
|
||||||
if(interp.workspace != null)
|
|
||||||
interp.workspace.put(this);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ FactorShuffleDefinition constructor
|
//{{{ FactorShuffleDefinition constructor
|
||||||
|
@ -162,8 +152,6 @@ public class FactorShuffleDefinition extends FactorWordDefinition
|
||||||
FactorArray callstack)
|
FactorArray callstack)
|
||||||
throws FactorStackException
|
throws FactorStackException
|
||||||
{
|
{
|
||||||
lazyInit(interp);
|
|
||||||
|
|
||||||
if(datastack.top < consumeD)
|
if(datastack.top < consumeD)
|
||||||
throw new FactorStackException(consumeD);
|
throw new FactorStackException(consumeD);
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,12 @@
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An internalized symbol.
|
* An internalized symbol.
|
||||||
*/
|
*/
|
||||||
public class FactorWord extends SimplePersistentObject
|
public class FactorWord implements FactorExternalizable, FactorObject
|
||||||
implements FactorExternalizable
|
|
||||||
{
|
{
|
||||||
private static int gensymCount = 0;
|
private static int gensymCount = 0;
|
||||||
|
|
||||||
|
@ -75,16 +73,7 @@ public class FactorWord extends SimplePersistentObject
|
||||||
public FactorClassLoader loader;
|
public FactorClassLoader loader;
|
||||||
public String className;
|
public String className;
|
||||||
|
|
||||||
//{{{ FactorWord constructor
|
private FactorNamespace namespace;
|
||||||
/**
|
|
||||||
* 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
|
//{{{ FactorWord constructor
|
||||||
/**
|
/**
|
||||||
|
@ -92,15 +81,12 @@ public class FactorWord extends SimplePersistentObject
|
||||||
* implementation or something. Use an FactorDictionary's
|
* implementation or something. Use an FactorDictionary's
|
||||||
* intern() method instead.
|
* intern() method instead.
|
||||||
*/
|
*/
|
||||||
public FactorWord(Workspace workspace, String vocabulary, String name,
|
public FactorWord(String vocabulary, String name,
|
||||||
FactorWordDefinition def) throws Exception
|
FactorWordDefinition def) throws Exception
|
||||||
{
|
{
|
||||||
this(workspace,workspace == null ? 0L : workspace.nextID());
|
|
||||||
this.vocabulary = vocabulary;
|
this.vocabulary = vocabulary;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.def = def;
|
this.def = def;
|
||||||
if(workspace != null && id != 0L)
|
|
||||||
workspace.put(this);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ FactorWord constructor
|
//{{{ FactorWord constructor
|
||||||
|
@ -115,6 +101,15 @@ public class FactorWord extends SimplePersistentObject
|
||||||
this.name = name;
|
this.name = name;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
//{{{ getNamespace() method
|
||||||
|
public FactorNamespace getNamespace()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if(namespace == null)
|
||||||
|
namespace = new FactorNamespace(this);
|
||||||
|
return namespace;
|
||||||
|
} //}}}
|
||||||
|
|
||||||
//{{{ gensym() method
|
//{{{ gensym() method
|
||||||
/**
|
/**
|
||||||
* Returns an un-internalized word with a unique name.
|
* Returns an un-internalized word with a unique name.
|
||||||
|
@ -126,7 +121,6 @@ public class FactorWord extends SimplePersistentObject
|
||||||
|
|
||||||
//{{{ define() method
|
//{{{ define() method
|
||||||
public synchronized void define(FactorWordDefinition def)
|
public synchronized void define(FactorWordDefinition def)
|
||||||
throws PersistenceException
|
|
||||||
{
|
{
|
||||||
if(compileRef)
|
if(compileRef)
|
||||||
{
|
{
|
||||||
|
@ -140,20 +134,14 @@ public class FactorWord extends SimplePersistentObject
|
||||||
|
|
||||||
loader = null;
|
loader = null;
|
||||||
className = null;
|
className = null;
|
||||||
|
|
||||||
if(workspace != null && id != 0L)
|
|
||||||
workspace.put(this);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ setCompiledInfo() method
|
//{{{ setCompiledInfo() method
|
||||||
synchronized void setCompiledInfo(FactorClassLoader loader,
|
synchronized void setCompiledInfo(FactorClassLoader loader,
|
||||||
String className) throws PersistenceException
|
String className)
|
||||||
{
|
{
|
||||||
this.loader = loader;
|
this.loader = loader;
|
||||||
this.className = className;
|
this.className = className;
|
||||||
|
|
||||||
if(workspace != null && id != 0L)
|
|
||||||
workspace.put(this);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ compile() method
|
//{{{ compile() method
|
||||||
|
@ -165,30 +153,6 @@ public class FactorWord extends SimplePersistentObject
|
||||||
recursiveCheck.remove(this);
|
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
|
//{{{ compile() method
|
||||||
public synchronized void compile(FactorInterpreter interp,
|
public synchronized void compile(FactorInterpreter interp,
|
||||||
RecursiveState recursiveCheck)
|
RecursiveState recursiveCheck)
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
|
|
||||||
package factor;
|
package factor;
|
||||||
|
|
||||||
import factor.db.*;
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -37,21 +36,9 @@ import org.objectweb.asm.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A word definition.
|
* 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
|
public abstract class FactorWordDefinition implements Constants
|
||||||
implements Constants, PersistentObject
|
|
||||||
{
|
{
|
||||||
public static final String ENCODING = "UTF8";
|
|
||||||
|
|
||||||
private String unparsed;
|
|
||||||
private boolean initialized;
|
|
||||||
|
|
||||||
private Workspace workspace;
|
|
||||||
private long id;
|
|
||||||
|
|
||||||
protected FactorWord word;
|
protected FactorWord word;
|
||||||
|
|
||||||
public boolean compileFailed;
|
public boolean compileFailed;
|
||||||
|
@ -60,32 +47,9 @@ public abstract class FactorWordDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* 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)
|
public FactorWordDefinition(FactorWord word)
|
||||||
{
|
{
|
||||||
this.word = word;
|
this.word = word;
|
||||||
initialized = true;
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public abstract void eval(FactorInterpreter interp)
|
public abstract void eval(FactorInterpreter interp)
|
||||||
|
@ -94,15 +58,14 @@ public abstract class FactorWordDefinition
|
||||||
//{{{ getWord() method
|
//{{{ getWord() method
|
||||||
public FactorWord getWord(FactorInterpreter interp)
|
public FactorWord getWord(FactorInterpreter interp)
|
||||||
{
|
{
|
||||||
lazyInit(interp);
|
|
||||||
return word;
|
return word;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ fromList() method
|
//{{{ fromList() method
|
||||||
public void fromList(Cons cons, FactorInterpreter interp)
|
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
|
//{{{ toList() method
|
||||||
|
@ -123,7 +86,6 @@ public abstract class FactorWordDefinition
|
||||||
FactorInterpreter interp) throws Exception
|
FactorInterpreter interp) throws Exception
|
||||||
{
|
{
|
||||||
FactorCompiler compiler = new FactorCompiler(interp);
|
FactorCompiler compiler = new FactorCompiler(interp);
|
||||||
lazyInit(interp);
|
|
||||||
recursiveCheck.add(word,new StackEffect(),null,null,null);
|
recursiveCheck.add(word,new StackEffect(),null,null,null);
|
||||||
getStackEffect(recursiveCheck,compiler);
|
getStackEffect(recursiveCheck,compiler);
|
||||||
recursiveCheck.remove(word);
|
recursiveCheck.remove(word);
|
||||||
|
@ -134,7 +96,6 @@ public abstract class FactorWordDefinition
|
||||||
public void getStackEffect(RecursiveState recursiveCheck,
|
public void getStackEffect(RecursiveState recursiveCheck,
|
||||||
FactorCompiler compiler) throws Exception
|
FactorCompiler compiler) throws Exception
|
||||||
{
|
{
|
||||||
lazyInit(compiler.interp);
|
|
||||||
throw new FactorCompilerException("Cannot deduce stack effect of " + word);
|
throw new FactorCompilerException("Cannot deduce stack effect of " + word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
@ -152,8 +113,6 @@ public abstract class FactorWordDefinition
|
||||||
public void compileCallTo(CodeVisitor mw, FactorCompiler compiler,
|
public void compileCallTo(CodeVisitor mw, FactorCompiler compiler,
|
||||||
RecursiveState recursiveCheck) throws Exception
|
RecursiveState recursiveCheck) throws Exception
|
||||||
{
|
{
|
||||||
lazyInit(compiler.interp);
|
|
||||||
|
|
||||||
// normal word
|
// normal word
|
||||||
String defclass;
|
String defclass;
|
||||||
String defmethod;
|
String defmethod;
|
||||||
|
@ -262,8 +221,6 @@ public abstract class FactorWordDefinition
|
||||||
RecursiveState recursiveCheck,
|
RecursiveState recursiveCheck,
|
||||||
StackEffect immediateEffect) throws Exception
|
StackEffect immediateEffect) throws Exception
|
||||||
{
|
{
|
||||||
lazyInit(compiler.interp);
|
|
||||||
|
|
||||||
Cons definition = toList(compiler.getInterpreter());
|
Cons definition = toList(compiler.getInterpreter());
|
||||||
|
|
||||||
Cons endOfDocs = definition;
|
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
|
//{{{ toString() method
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,6 @@ import org.objectweb.asm.*;
|
||||||
*/
|
*/
|
||||||
public abstract class CompiledDefinition
|
public abstract class CompiledDefinition
|
||||||
extends FactorWordDefinition
|
extends FactorWordDefinition
|
||||||
implements factor.db.PersistentIgnore
|
|
||||||
{
|
{
|
||||||
//{{{ CompiledDefinition constructor
|
//{{{ CompiledDefinition constructor
|
||||||
public CompiledDefinition(FactorWord word)
|
public CompiledDefinition(FactorWord word)
|
||||||
|
|
|
@ -29,9 +29,7 @@
|
||||||
|
|
||||||
package factor.compiler;
|
package factor.compiler;
|
||||||
|
|
||||||
import factor.Cons;
|
import factor.*;
|
||||||
import factor.FactorInterpreter;
|
|
||||||
import factor.db.*;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,28 +38,10 @@ import java.util.*;
|
||||||
* When compiling a word; add each dependent word to new class loader's
|
* When compiling a word; add each dependent word to new class loader's
|
||||||
* delegates map.
|
* delegates map.
|
||||||
*/
|
*/
|
||||||
public class FactorClassLoader extends ClassLoader implements PersistentObject
|
public class FactorClassLoader extends ClassLoader
|
||||||
{
|
{
|
||||||
private Workspace workspace;
|
|
||||||
private long id;
|
private long id;
|
||||||
private Table table;
|
private FactorNamespace table = new FactorNamespace();
|
||||||
|
|
||||||
//{{{ 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());
|
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ addDependency() method
|
//{{{ addDependency() method
|
||||||
public void addDependency(String name, FactorClassLoader loader)
|
public void addDependency(String name, FactorClassLoader loader)
|
||||||
|
@ -69,8 +49,6 @@ public class FactorClassLoader extends ClassLoader implements PersistentObject
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
table.setVariable(name,loader);
|
table.setVariable(name,loader);
|
||||||
if(workspace != null && id != 0L)
|
|
||||||
workspace.put(this);
|
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
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
|
//{{{ addClass() method
|
||||||
public Class addClass(String name, byte[] code, int off, int len)
|
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);
|
return defineClass(name,code,off,len);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
@ -153,16 +83,6 @@ public class FactorClassLoader extends ClassLoader implements PersistentObject
|
||||||
return ((FactorClassLoader)obj)
|
return ((FactorClassLoader)obj)
|
||||||
.loadClass(name,resolve);
|
.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)
|
else if(obj != null)
|
||||||
{
|
{
|
||||||
System.err.println("WARNING: unknown object in class loader table for " + this + ": " + obj);
|
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);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ getReferences() method
|
|
||||||
public Cons getReferences()
|
|
||||||
{
|
|
||||||
return table.getReferences();
|
|
||||||
} //}}}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
} //}}}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
} //}}}
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
{
|
|
||||||
} //}}}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
} //}}}
|
|
||||||
}
|
|
|
@ -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 {}
|
|
|
@ -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();
|
|
||||||
}
|
|
|
@ -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()
|
|
||||||
{
|
|
||||||
} //}}}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
} //}}}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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());
|
|
||||||
} //}}}
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} //}}}
|
|
||||||
}
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Bar extends FactorParsingDefinition
|
public class Bar extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -38,10 +37,10 @@ public class Bar extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Bar(FactorWord word, Workspace workspace)
|
public Bar(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Base extends FactorParsingDefinition
|
public class Base extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -40,10 +39,10 @@ public class Base extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Base(FactorWord word, Workspace workspace, int base)
|
public Base(FactorWord word, int base)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
this.base = base;
|
this.base = base;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Bra extends FactorParsingDefinition
|
public class Bra extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -38,10 +37,10 @@ public class Bra extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Bra(FactorWord word, Workspace workspace)
|
public Bra(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class CharLiteral extends FactorParsingDefinition
|
public class CharLiteral extends FactorParsingDefinition
|
||||||
|
@ -39,20 +38,10 @@ public class CharLiteral extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public CharLiteral(FactorWord word, Workspace workspace)
|
public CharLiteral(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ CharLiteral constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public CharLiteral(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.math.*;
|
import factor.math.*;
|
||||||
|
|
||||||
public class ComplexLiteral extends FactorParsingDefinition
|
public class ComplexLiteral extends FactorParsingDefinition
|
||||||
|
@ -41,11 +40,10 @@ public class ComplexLiteral extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public ComplexLiteral(FactorWord word,
|
public ComplexLiteral(FactorWord word, String end)
|
||||||
String end, Workspace workspace)
|
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
this.end = end;
|
this.end = end;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Def extends FactorParsingDefinition
|
public class Def extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -38,10 +37,10 @@ public class Def extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Def(FactorWord word, Workspace workspace)
|
public Def(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Defer extends FactorParsingDefinition
|
public class Defer extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -38,10 +37,10 @@ public class Defer extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Defer(FactorWord word, Workspace workspace)
|
public Defer(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class Dispatch extends FactorParsingDefinition
|
public class Dispatch extends FactorParsingDefinition
|
||||||
|
@ -39,10 +38,10 @@ public class Dispatch extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Dispatch(FactorWord word, Workspace workspace)
|
public Dispatch(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class F extends FactorParsingDefinition
|
public class F extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -38,10 +37,10 @@ public class F extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public F(FactorWord word, Workspace workspace)
|
public F(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class In extends FactorParsingDefinition
|
public class In extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -38,10 +37,10 @@ public class In extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public In(FactorWord word, Workspace workspace)
|
public In(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Ine extends FactorParsingDefinition
|
public class Ine extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -40,10 +39,10 @@ public class Ine extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Ine(FactorWord start, FactorWord end, Workspace workspace)
|
public Ine(FactorWord start, FactorWord end)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(end,workspace);
|
super(end);
|
||||||
this.start = start;
|
this.start = start;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Ket extends FactorParsingDefinition
|
public class Ket extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -40,10 +39,10 @@ public class Ket extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Ket(FactorWord start, FactorWord end, Workspace workspace)
|
public Ket(FactorWord start, FactorWord end)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(end,workspace);
|
super(end);
|
||||||
this.start = start;
|
this.start = start;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class LineComment extends FactorParsingDefinition
|
public class LineComment extends FactorParsingDefinition
|
||||||
|
@ -41,10 +40,10 @@ public class LineComment extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public LineComment(FactorWord word, boolean doc, Workspace workspace)
|
public LineComment(FactorWord word, boolean doc)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
this.doc = doc;
|
this.doc = doc;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class NoParsing extends FactorParsingDefinition
|
public class NoParsing extends FactorParsingDefinition
|
||||||
|
@ -39,10 +38,10 @@ public class NoParsing extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public NoParsing(FactorWord word, Workspace workspace)
|
public NoParsing(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class PassThrough extends FactorParsingDefinition
|
public class PassThrough extends FactorParsingDefinition
|
||||||
|
@ -39,10 +38,10 @@ public class PassThrough extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public PassThrough(FactorWord word, Workspace workspace)
|
public PassThrough(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Shuffle extends FactorParsingDefinition
|
public class Shuffle extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -40,10 +39,10 @@ public class Shuffle extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Shuffle(FactorWord word, String end, Workspace workspace)
|
public Shuffle(FactorWord word, String end)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
this.end = end;
|
this.end = end;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class StackComment extends FactorParsingDefinition
|
public class StackComment extends FactorParsingDefinition
|
||||||
|
@ -39,10 +38,10 @@ public class StackComment extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public StackComment(FactorWord word, Workspace workspace)
|
public StackComment(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class StringLiteral extends FactorParsingDefinition
|
public class StringLiteral extends FactorParsingDefinition
|
||||||
|
@ -41,11 +40,10 @@ public class StringLiteral extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public StringLiteral(FactorWord word, boolean escapes,
|
public StringLiteral(FactorWord word, boolean escapes)
|
||||||
Workspace workspace)
|
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
this.escapes = escapes;
|
this.escapes = escapes;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class T extends FactorParsingDefinition
|
public class T extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -38,10 +37,10 @@ public class T extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public T(FactorWord word, Workspace workspace)
|
public T(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class Unreadable extends FactorParsingDefinition
|
public class Unreadable extends FactorParsingDefinition
|
||||||
|
@ -39,10 +38,10 @@ public class Unreadable extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Unreadable(FactorWord word, Workspace workspace)
|
public Unreadable(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
public void eval(FactorInterpreter interp, FactorReader reader)
|
public void eval(FactorInterpreter interp, FactorReader reader)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.parser;
|
package factor.parser;
|
||||||
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import factor.db.*;
|
|
||||||
|
|
||||||
public class Use extends FactorParsingDefinition
|
public class Use extends FactorParsingDefinition
|
||||||
{
|
{
|
||||||
|
@ -38,10 +37,10 @@ public class Use extends FactorParsingDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Use(FactorWord word, Workspace workspace)
|
public Use(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
!a;1592;1592
|
!a;1572;1572
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
!a;1536;1536
|
!a;1494;1494
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
!a;1592;1592
|
!a;1572;1572
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
!a;1592;1592
|
!a;1572;1572
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
!a;1592;1592
|
!a;1572;1572
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,20 +41,9 @@ public class Call extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Call(FactorWord word, Workspace workspace)
|
public Call(FactorWord word)
|
||||||
throws Exception
|
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ Call constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public Call(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,9 +30,7 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.util.Set;
|
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
public class Coerce extends FactorPrimitiveDefinition
|
public class Coerce extends FactorPrimitiveDefinition
|
||||||
|
@ -41,20 +39,10 @@ public class Coerce extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Coerce(FactorWord word, Workspace workspace)
|
public Coerce(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ Coerce constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public Coerce(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,9 +30,7 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Define extends FactorPrimitiveDefinition
|
public class Define extends FactorPrimitiveDefinition
|
||||||
{
|
{
|
||||||
|
@ -40,20 +38,10 @@ public class Define extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Define(FactorWord word, Workspace workspace)
|
public Define(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ Define constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public Define(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -42,20 +41,10 @@ public class Execute extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Execute(FactorWord word, Workspace workspace)
|
public Execute(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ Execute constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public Execute(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
|
@ -40,20 +39,10 @@ public class Ifte extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Ifte(FactorWord word, Workspace workspace)
|
public Ifte(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ Ifte constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public Ifte(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
@ -41,20 +40,10 @@ public class InterpreterGet extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public InterpreterGet(FactorWord word, Workspace workspace)
|
public InterpreterGet(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ InterpreterGet constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public InterpreterGet(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -44,24 +43,13 @@ public class JInvoke extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public JInvoke(FactorWord word, Workspace workspace,
|
public JInvoke(FactorWord word, boolean staticMethod)
|
||||||
boolean staticMethod)
|
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
this.staticMethod = staticMethod;
|
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
|
//{{{ checkStatic() method
|
||||||
private void checkStatic(Method method) throws FactorRuntimeException
|
private void checkStatic(Method method) throws FactorRuntimeException
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,20 +41,10 @@ public class JNew extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public JNew(FactorWord word, Workspace workspace)
|
public JNew(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ JNew constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public JNew(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,20 +41,10 @@ public class JVarGet extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public JVarGet(FactorWord word, Workspace workspace)
|
public JVarGet(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ JVarGet constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public JVarGet(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,20 +41,10 @@ public class JVarGetStatic extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public JVarGetStatic(FactorWord word, Workspace workspace)
|
public JVarGetStatic(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ JVarGetStatic constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public JVarGetStatic(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,20 +41,10 @@ public class JVarSet extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public JVarSet(FactorWord word, Workspace workspace)
|
public JVarSet(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ JVarSet constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public JVarSet(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,20 +41,10 @@ public class JVarSetStatic extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public JVarSetStatic(FactorWord word, Workspace workspace)
|
public JVarSetStatic(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ JVarSetStatic constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public JVarSetStatic(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -40,20 +39,10 @@ public class Restack extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Restack(FactorWord word, Workspace workspace)
|
public Restack(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ Restack constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public Restack(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
package factor.primitives;
|
package factor.primitives;
|
||||||
|
|
||||||
import factor.compiler.*;
|
import factor.compiler.*;
|
||||||
import factor.db.*;
|
|
||||||
import factor.*;
|
import factor.*;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -40,20 +39,10 @@ public class Unstack extends FactorPrimitiveDefinition
|
||||||
/**
|
/**
|
||||||
* A new definition.
|
* A new definition.
|
||||||
*/
|
*/
|
||||||
public Unstack(FactorWord word, Workspace workspace)
|
public Unstack(FactorWord word)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super(word,workspace);
|
super(word);
|
||||||
} //}}}
|
|
||||||
|
|
||||||
//{{{ Unstack constructor
|
|
||||||
/**
|
|
||||||
* A blank definition, about to be unpickled.
|
|
||||||
*/
|
|
||||||
public Unstack(Workspace workspace, long id)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super(workspace,id);
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
//{{{ eval() method
|
//{{{ eval() method
|
||||||
|
|
|
@ -29,9 +29,9 @@ IN: errors
|
||||||
USE: combinators
|
USE: combinators
|
||||||
USE: continuations
|
USE: continuations
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: inspector
|
|
||||||
USE: logic
|
USE: logic
|
||||||
USE: namespaces
|
USE: namespaces
|
||||||
|
USE: prettyprint
|
||||||
USE: stack
|
USE: stack
|
||||||
USE: stdio
|
USE: stdio
|
||||||
USE: strings
|
USE: strings
|
||||||
|
@ -65,14 +65,7 @@ USE: unparser
|
||||||
|
|
||||||
suspend ;
|
suspend ;
|
||||||
|
|
||||||
: ?describe-stack ( stack -- )
|
: :s ( -- ) "error-datastack" get prettyprint ;
|
||||||
dup [
|
: :r ( -- ) "error-callstack" get prettyprint ;
|
||||||
describe-stack
|
: :n ( -- ) "error-namestack" get prettyprint ;
|
||||||
] [
|
: :c ( -- ) "error-catchstack" get prettyprint ;
|
||||||
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 ;
|
|
||||||
|
|
|
@ -36,18 +36,11 @@ USE: stack
|
||||||
USE: strings
|
USE: strings
|
||||||
USE: vectors
|
USE: vectors
|
||||||
|
|
||||||
: >c ( catch -- )
|
: >c ( catch -- ) catchstack* vector-push ;
|
||||||
#! Push a catch block on the catchstack. Use the catch word
|
: c> ( catch -- ) catchstack* vector-pop ;
|
||||||
#! 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 ;
|
|
||||||
|
|
||||||
: save-error ( error -- )
|
: save-error ( error -- )
|
||||||
#! Save the stacks for most-mortem inspection after an
|
#! Save the stacks for post-mortem inspection after an
|
||||||
#! error.
|
#! error.
|
||||||
global [
|
global [
|
||||||
"error" set
|
"error" set
|
||||||
|
@ -58,18 +51,14 @@ USE: vectors
|
||||||
] bind ;
|
] bind ;
|
||||||
|
|
||||||
: catch ( try catch -- )
|
: catch ( try catch -- )
|
||||||
#! Call the try quotation, restore the datastack to its
|
#! Call the try quotation. If an error occurs restore the
|
||||||
#! state before the try quotation, push the error (or f if
|
#! datastack, push the error, and call the catch block.
|
||||||
#! no error occurred) and call the catch quotation.
|
#! If no error occurs, push f and call the catch block.
|
||||||
[ >c >r call c> drop f r> f ] callcc1
|
[ >c >r call c> drop f r> f ] callcc1 rot drop swap call ;
|
||||||
( try catch error ) rot drop swap ( error catch ) call ;
|
|
||||||
|
|
||||||
: rethrow ( error -- )
|
: rethrow ( error -- )
|
||||||
#! Use rethrow when passing an error on from a catch block.
|
#! Use rethrow when passing an error on from a catch block.
|
||||||
#! For convinience, this word is a no-op if error is f.
|
#! For convinience, this word is a no-op if error is f.
|
||||||
[ c> call ] when* ;
|
[ c> call ] when* ;
|
||||||
|
|
||||||
: throw ( error -- )
|
: throw ( error -- ) dup save-error rethrow ;
|
||||||
#! Throw an error. If no catch handlers are installed, the
|
|
||||||
#! default-error-handler is called.
|
|
||||||
dup save-error rethrow ;
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ USE: wiki-responder
|
||||||
: default-responders ( -- )
|
: default-responders ( -- )
|
||||||
#! Remove all existing responders, and create a blank
|
#! Remove all existing responders, and create a blank
|
||||||
#! responder table.
|
#! responder table.
|
||||||
<table> [
|
<namespace> [
|
||||||
<responder> [
|
<responder> [
|
||||||
"test" "responder" set
|
"test" "responder" set
|
||||||
[ test-responder ] "get" set
|
[ test-responder ] "get" set
|
||||||
|
@ -63,7 +63,7 @@ USE: wiki-responder
|
||||||
"wiki" "responder" set
|
"wiki" "responder" set
|
||||||
[ wiki-get-responder ] "get" set
|
[ wiki-get-responder ] "get" set
|
||||||
[ wiki-post-responder ] "post" set
|
[ wiki-post-responder ] "post" set
|
||||||
<table> "wiki" set
|
<namespace> "wiki" set
|
||||||
"WikiHome" "default-argument" set
|
"WikiHome" "default-argument" set
|
||||||
] extend "wiki" set
|
] extend "wiki" set
|
||||||
] extend "httpd-responders" set ;
|
] extend "httpd-responders" set ;
|
||||||
|
|
|
@ -39,7 +39,7 @@ USE: strings
|
||||||
USE: httpd
|
USE: httpd
|
||||||
|
|
||||||
: <responder> ( -- responder )
|
: <responder> ( -- responder )
|
||||||
<table> [
|
<namespace> [
|
||||||
[
|
[
|
||||||
drop "GET method not implemented" httpd-error
|
drop "GET method not implemented" httpd-error
|
||||||
] "get" set
|
] "get" set
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
IN: inspector
|
IN: inspector
|
||||||
USE: combinators
|
USE: combinators
|
||||||
USE: errors
|
|
||||||
USE: format
|
USE: format
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
|
@ -82,14 +81,6 @@ USE: vocabularies
|
||||||
[ prettyprint terpri ]
|
[ prettyprint terpri ]
|
||||||
] cond ;
|
] cond ;
|
||||||
|
|
||||||
: describe-stack ( vector -- )
|
|
||||||
stack>list [.] ;
|
|
||||||
|
|
||||||
: .n namestack describe-stack ;
|
|
||||||
: .s datastack describe-stack ;
|
|
||||||
: .r callstack describe-stack ;
|
|
||||||
: .c catchstack describe-stack ;
|
|
||||||
|
|
||||||
: describe-object-path ( string -- )
|
: describe-object-path ( string -- )
|
||||||
<namespace> [
|
<namespace> [
|
||||||
dup "object-path" set
|
dup "object-path" set
|
||||||
|
|
|
@ -69,7 +69,6 @@ USE: parser
|
||||||
"/library/stdio.factor" run-resource ! stdio
|
"/library/stdio.factor" run-resource ! stdio
|
||||||
"/library/platform/jvm/unparser.factor" run-resource ! unparser
|
"/library/platform/jvm/unparser.factor" run-resource ! unparser
|
||||||
"/library/platform/jvm/parser.factor" run-resource ! parser
|
"/library/platform/jvm/parser.factor" run-resource ! parser
|
||||||
"/library/platform/jvm/workspace.factor" run-resource ! workspace
|
|
||||||
"/library/styles.factor" run-resource ! styles
|
"/library/styles.factor" run-resource ! styles
|
||||||
|
|
||||||
!!! Math library.
|
!!! Math library.
|
||||||
|
|
|
@ -70,7 +70,6 @@ USE: parser
|
||||||
"/library/stdio.factor" run-resource ! stdio
|
"/library/stdio.factor" run-resource ! stdio
|
||||||
"/library/platform/jvm/unparser.factor" run-resource ! unparser
|
"/library/platform/jvm/unparser.factor" run-resource ! unparser
|
||||||
"/library/platform/jvm/parser.factor" run-resource ! parser
|
"/library/platform/jvm/parser.factor" run-resource ! parser
|
||||||
"/library/platform/jvm/workspace.factor" run-resource ! workspace
|
|
||||||
"/library/styles.factor" run-resource ! styles
|
"/library/styles.factor" run-resource ! styles
|
||||||
"/library/platform/jvm/threads.factor" run-resource ! threads
|
"/library/platform/jvm/threads.factor" run-resource ! threads
|
||||||
"/library/logging.factor" run-resource ! logging
|
"/library/logging.factor" run-resource ! logging
|
||||||
|
|
|
@ -118,5 +118,7 @@ USE: strings
|
||||||
compile-all
|
compile-all
|
||||||
] when
|
] when
|
||||||
|
|
||||||
|
t "startup-done" set
|
||||||
|
|
||||||
print-banner
|
print-banner
|
||||||
init-interpreter ;
|
init-interpreter ;
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
!:folding=indent: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.
|
|
||||||
|
|
||||||
!!! A "store" is a flat-file database that identifies byte
|
|
||||||
!!! arrays with 8-byte keys. Several implementations are
|
|
||||||
!!! available. There are several low-level words for creating
|
|
||||||
!!! and working with your own stores, but usually these words
|
|
||||||
!!! are only used for testing.
|
|
||||||
!!!
|
|
||||||
!!! A "workspace" sits on top of a store and implements
|
|
||||||
!!! picking/unpickling of persistent objects in the store.
|
|
||||||
!!!
|
|
||||||
!!! Each persistent object has an 8-byte ID; this is the same
|
|
||||||
!!! ID used to save/load the object in the store.
|
|
||||||
!!!
|
|
||||||
!!! Additinally, each persistent object knows how to
|
|
||||||
!!! pickle/unpickle itself.
|
|
||||||
|
|
||||||
IN: workspace
|
|
||||||
USE: combinators
|
|
||||||
USE: namespaces
|
|
||||||
USE: stack
|
|
||||||
USE: streams
|
|
||||||
|
|
||||||
: workspace ( -- workspace )
|
|
||||||
#! Push the current workspace.
|
|
||||||
interpreter [ "workspace" get ] bind ;
|
|
||||||
|
|
||||||
: <btree-store> ( filename order readonly -- store )
|
|
||||||
#! Create a B-tree store. The B-tree store puts all records
|
|
||||||
#! inside a single file, using an auxiliary file holding a
|
|
||||||
#! B-tree to implement fast searches.
|
|
||||||
[ <file> ] 2dip
|
|
||||||
[ "java.io.File" "byte" "boolean" ]
|
|
||||||
"factor.db.BTreeStore" jnew ;
|
|
||||||
|
|
||||||
: <file-store> ( filename -- store )
|
|
||||||
#! Create a file store. The file store puts all records
|
|
||||||
#! inside individual files in a directory.
|
|
||||||
[ "java.lang.String" ] "factor.db.FileStore" jnew ;
|
|
||||||
|
|
||||||
: store-get ( id store -- )
|
|
||||||
#! Retreive a value from the store.
|
|
||||||
[ "long" ] "factor.db.Store" "loadFromStore"
|
|
||||||
jinvoke ;
|
|
||||||
|
|
||||||
: store-set ( id value store -- )
|
|
||||||
#! Put a value in the store.
|
|
||||||
[ "long" [ "byte" ] ] "factor.db.Store" "saveToStore"
|
|
||||||
jinvoke ;
|
|
||||||
|
|
||||||
: in-store? ( id store -- ? )
|
|
||||||
#! Check if a value is in the store.
|
|
||||||
[ "long" ] "factor.db.Store" "exists" jinvoke ;
|
|
||||||
|
|
||||||
: close-store ( store -- )
|
|
||||||
#! Close a store, completing all pending transactions.
|
|
||||||
[ ] "factor.db.Store" "close" jinvoke ;
|
|
||||||
|
|
||||||
: save-workspace ( -- )
|
|
||||||
#! Complete all pending transactions in the workspace.
|
|
||||||
workspace [ ] "factor.db.Workspace" "flush" jinvoke ;
|
|
||||||
|
|
||||||
IN: namespaces
|
|
||||||
|
|
||||||
: <table> ( -- table )
|
|
||||||
#! A table is a persistent namespace.
|
|
||||||
workspace
|
|
||||||
[ "factor.db.Workspace" ] "factor.db.Table" jnew ;
|
|
||||||
|
|
||||||
: alist>table ( alist -- table )
|
|
||||||
<table> tuck alist> ;
|
|
|
@ -85,6 +85,3 @@ DEFER: >n
|
||||||
: namespace-of ;
|
: namespace-of ;
|
||||||
: this namespace ;
|
: this namespace ;
|
||||||
: has-namespace? hashtable? ;
|
: has-namespace? hashtable? ;
|
||||||
|
|
||||||
! We don't have a workspace in native Factor.
|
|
||||||
: <table> <namespace> ;
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
IN: prettyprint
|
IN: prettyprint
|
||||||
USE: arithmetic
|
USE: arithmetic
|
||||||
USE: combinators
|
USE: combinators
|
||||||
|
USE: errors
|
||||||
USE: format
|
USE: format
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: logic
|
USE: logic
|
||||||
|
@ -39,6 +40,7 @@ USE: stdio
|
||||||
USE: strings
|
USE: strings
|
||||||
USE: styles
|
USE: styles
|
||||||
USE: unparser
|
USE: unparser
|
||||||
|
USE: vectors
|
||||||
USE: vocabularies
|
USE: vocabularies
|
||||||
USE: words
|
USE: words
|
||||||
|
|
||||||
|
@ -75,6 +77,22 @@ DEFER: prettyprint*
|
||||||
: prettyprint-[] ( indent list -- indent )
|
: prettyprint-[] ( indent list -- indent )
|
||||||
swap prettyprint-[ swap prettyprint-list prettyprint-] ;
|
swap prettyprint-[ swap prettyprint-list prettyprint-] ;
|
||||||
|
|
||||||
|
: prettyprint-{ ( indent -- indent )
|
||||||
|
"{" write
|
||||||
|
tab-size + dup prettyprint-newline ;
|
||||||
|
|
||||||
|
: prettyprint-} ( indent -- indent )
|
||||||
|
tab-size - dup prettyprint-newline
|
||||||
|
"}" write
|
||||||
|
prettyprint-space ;
|
||||||
|
|
||||||
|
: prettyprint-vector ( indent list -- indent )
|
||||||
|
#! Pretty-print a vector, without { and }.
|
||||||
|
[ prettyprint* ] vector-each ;
|
||||||
|
|
||||||
|
: prettyprint-{} ( indent list -- indent )
|
||||||
|
swap prettyprint-{ swap prettyprint-vector prettyprint-} ;
|
||||||
|
|
||||||
: write-comment ( comment -- )
|
: write-comment ( comment -- )
|
||||||
[ "comments" ] get-style [ write-attr ] bind ;
|
[ "comments" ] get-style [ write-attr ] bind ;
|
||||||
|
|
||||||
|
@ -112,6 +130,7 @@ DEFER: prettyprint*
|
||||||
[
|
[
|
||||||
[ not ] [ prettyprint-object ]
|
[ not ] [ prettyprint-object ]
|
||||||
[ list? ] [ prettyprint-[] ]
|
[ list? ] [ prettyprint-[] ]
|
||||||
|
[ vector? ] [ prettyprint-{} ]
|
||||||
[ comment? ] [ prettyprint-comment ]
|
[ comment? ] [ prettyprint-comment ]
|
||||||
[ word? ] [ prettyprint-word ]
|
[ word? ] [ prettyprint-word ]
|
||||||
[ drop t ] [ prettyprint-object ]
|
[ drop t ] [ prettyprint-object ]
|
||||||
|
@ -131,3 +150,8 @@ DEFER: prettyprint*
|
||||||
: prettyprint-:; ( indent word list -- indent )
|
: prettyprint-:; ( indent word list -- indent )
|
||||||
[ [ prettyprint-: ] dip prettyprint-word ] dip
|
[ [ prettyprint-: ] dip prettyprint-word ] dip
|
||||||
prettyprint-list prettyprint-; ;
|
prettyprint-list prettyprint-; ;
|
||||||
|
|
||||||
|
: .n namestack prettyprint ;
|
||||||
|
: .s datastack prettyprint ;
|
||||||
|
: .r callstack prettyprint ;
|
||||||
|
: .c catchstack prettyprint ;
|
||||||
|
|
|
@ -67,9 +67,9 @@ USE: stack
|
||||||
|
|
||||||
: init-styles ( -- )
|
: init-styles ( -- )
|
||||||
|
|
||||||
<table> "styles" set
|
<namespace> "styles" set
|
||||||
"styles" get [
|
"styles" get [
|
||||||
<table> [
|
<namespace> [
|
||||||
f "ansi-fg" set
|
f "ansi-fg" set
|
||||||
f "ansi-bg" set
|
f "ansi-bg" set
|
||||||
f "fg" set
|
f "fg" set
|
||||||
|
@ -82,7 +82,7 @@ USE: stack
|
||||||
] extend "default" set
|
] extend "default" set
|
||||||
|
|
||||||
! A paragraph break
|
! A paragraph break
|
||||||
<table> [
|
<namespace> [
|
||||||
t "paragraph" set
|
t "paragraph" set
|
||||||
] extend "paragraph" set
|
] extend "paragraph" set
|
||||||
] bind
|
] bind
|
||||||
|
|
|
@ -2,7 +2,6 @@ IN: scratchpad
|
||||||
USE: arithmetic
|
USE: arithmetic
|
||||||
USE: combinators
|
USE: combinators
|
||||||
USE: compiler
|
USE: compiler
|
||||||
USE: inspector
|
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: lists
|
USE: lists
|
||||||
USE: logic
|
USE: logic
|
||||||
|
|
|
@ -44,8 +44,6 @@ USE: vocabularies
|
||||||
|
|
||||||
[ [ 5 1 0 0 ] ] [ [ >=< ] ] [ balance>list ] test-word
|
[ [ 5 1 0 0 ] ] [ [ >=< ] ] [ balance>list ] test-word
|
||||||
|
|
||||||
[ [ 1 0 0 0 ] ] [ [ throw ] ] [ balance>list ] test-word
|
|
||||||
|
|
||||||
[ [ 1 0 0 0 ] ] [ [ exit* ] ] [ balance>list ] test-word
|
[ [ 1 0 0 0 ] ] [ [ exit* ] ] [ balance>list ] test-word
|
||||||
|
|
||||||
[ [ 0 1 0 0 ] ] [ [ millis ] ] [ balance>list ] test-word
|
[ [ 0 1 0 0 ] ] [ [ millis ] ] [ balance>list ] test-word
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
!"Reboot test." print
|
|
||||||
!
|
|
||||||
!"reboot-test" get [
|
|
||||||
! t "reboot-test" set
|
|
||||||
!
|
|
||||||
! <namespace> [
|
|
||||||
! 1024 <string-output-stream> "stdio" set
|
|
||||||
!
|
|
||||||
! words [ worddef primitive? not ] subset [ see ] each
|
|
||||||
!
|
|
||||||
! "stdio" get stream>str dup parse
|
|
||||||
! ] bind
|
|
||||||
!
|
|
||||||
! call
|
|
||||||
!
|
|
||||||
! "compile" get [ compile-all ] when
|
|
||||||
!
|
|
||||||
! all-tests
|
|
||||||
!
|
|
||||||
! f "reboot-test" set
|
|
||||||
!] unless
|
|
||||||
!
|
|
||||||
!"Reboot test done." print
|
|
|
@ -1,31 +0,0 @@
|
||||||
IN: scratchpad
|
|
||||||
USE: arithmetic
|
|
||||||
USE: kernel
|
|
||||||
USE: stack
|
|
||||||
USE: stdio
|
|
||||||
USE: streams
|
|
||||||
USE: test
|
|
||||||
USE: workspace
|
|
||||||
|
|
||||||
! Now do a little benchmark.
|
|
||||||
|
|
||||||
: store-benchmark ( count store -- )
|
|
||||||
over [ over dupd store-set ] times*
|
|
||||||
over [ over store-get drop ] times*
|
|
||||||
2drop ; word must-compile
|
|
||||||
|
|
||||||
"Time to read/write a million entries with B-tree/127: " write
|
|
||||||
|
|
||||||
"btree-store-test" fdelete drop
|
|
||||||
"btree-store-test.index" fdelete drop
|
|
||||||
|
|
||||||
1000000 "btree-store-test" 127 f <btree-store>
|
|
||||||
|
|
||||||
[ store-benchmark ] time
|
|
||||||
|
|
||||||
!"Time to read/write a million entries with file store: " write
|
|
||||||
!
|
|
||||||
![ "rm" "-rf" "file-store-test" ] exec
|
|
||||||
!1000000 "file-store-test" <file-store>
|
|
||||||
!
|
|
||||||
![ store-benchmark ] time
|
|
|
@ -1,92 +0,0 @@
|
||||||
IN: scratchpad
|
|
||||||
USE: arithmetic
|
|
||||||
USE: combinators
|
|
||||||
USE: kernel
|
|
||||||
USE: lists
|
|
||||||
USE: random
|
|
||||||
USE: stack
|
|
||||||
USE: stdio
|
|
||||||
USE: streams
|
|
||||||
USE: strings
|
|
||||||
USE: test
|
|
||||||
USE: workspace
|
|
||||||
|
|
||||||
: bytes>string ( bytes -- string )
|
|
||||||
"ASCII" [ [ "byte" ] "java.lang.String" ]
|
|
||||||
"java.lang.String" jnew ; word must-compile
|
|
||||||
|
|
||||||
: store-num ( x store -- )
|
|
||||||
2dup in-store? [
|
|
||||||
2drop
|
|
||||||
] [
|
|
||||||
dupd store-set
|
|
||||||
] ifte ; word must-compile
|
|
||||||
|
|
||||||
: check-num ( x store -- )
|
|
||||||
! Check that it exists first
|
|
||||||
2dup in-store? assert
|
|
||||||
! Now check that its value is correct
|
|
||||||
[ dup >str swap ] dip store-get bytes>string assert= ;
|
|
||||||
|
|
||||||
: random-list ( count -- list )
|
|
||||||
[ ] swap [ 0 10000000 random-int swons ] times ; word must-compile
|
|
||||||
|
|
||||||
: test-store ( store list -- )
|
|
||||||
2dup
|
|
||||||
[ over store-num ] each drop
|
|
||||||
[ over check-num ] each close-store ;
|
|
||||||
|
|
||||||
!"File store test" print
|
|
||||||
!
|
|
||||||
![ "rm" "-rf" "file-store-test" ] exec
|
|
||||||
!"file-store-test" <file-store> test-store
|
|
||||||
|
|
||||||
"B-tree store test" print
|
|
||||||
|
|
||||||
: delete-btree-test ( -- )
|
|
||||||
"btree-store-test" fdelete drop
|
|
||||||
"btree-store-test.index" fdelete drop ;
|
|
||||||
|
|
||||||
: create-btree-test ( order -- store )
|
|
||||||
delete-btree-test
|
|
||||||
"btree-store-test" swap f <btree-store> ;
|
|
||||||
|
|
||||||
: btree-test ( order list -- )
|
|
||||||
[ create-btree-test ] dip test-store ;
|
|
||||||
|
|
||||||
: btree-random-test ( order count -- )
|
|
||||||
"B-tree test #1: " write 2dup " " swap cat3 print
|
|
||||||
random-list [ btree-test ] time ;
|
|
||||||
|
|
||||||
4 2000 btree-random-test
|
|
||||||
5 2000 btree-random-test
|
|
||||||
6 2000 btree-random-test
|
|
||||||
7 2000 btree-random-test
|
|
||||||
8 2000 btree-random-test
|
|
||||||
48 5000 btree-random-test
|
|
||||||
127 10000 btree-random-test
|
|
||||||
|
|
||||||
: test-add-or-get ( x store -- )
|
|
||||||
random-boolean [
|
|
||||||
store-num
|
|
||||||
] [
|
|
||||||
in-store? drop
|
|
||||||
] ifte ; word must-compile
|
|
||||||
|
|
||||||
: test-store-2 ( store list -- )
|
|
||||||
[ over test-add-or-get ] each close-store ; word must-compile
|
|
||||||
|
|
||||||
: btree-test-2 ( order list -- )
|
|
||||||
[ create-btree-test ] dip test-store-2 ;
|
|
||||||
|
|
||||||
: btree-random-test-2 ( order count -- )
|
|
||||||
"B-tree test #2: " write 2dup " " swap cat3 print
|
|
||||||
random-list [ btree-test-2 ] time ;
|
|
||||||
|
|
||||||
4 2000 btree-random-test-2
|
|
||||||
5 2000 btree-random-test-2
|
|
||||||
6 2000 btree-random-test-2
|
|
||||||
7 2000 btree-random-test-2
|
|
||||||
8 2000 btree-random-test-2
|
|
||||||
48 5000 btree-random-test-2
|
|
||||||
127 10000 btree-random-test-2
|
|
|
@ -81,8 +81,6 @@ USE: vocabularies
|
||||||
"tail"
|
"tail"
|
||||||
"types"
|
"types"
|
||||||
"vectors"
|
"vectors"
|
||||||
!"store"
|
|
||||||
!"reboot"
|
|
||||||
] [
|
] [
|
||||||
test
|
test
|
||||||
] each
|
] each
|
||||||
|
|
|
@ -51,7 +51,7 @@ USE: words
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: init-vocab-styles ( -- )
|
: init-vocab-styles ( -- )
|
||||||
"styles" get [ <table> "vocabularies" set ] bind
|
"styles" get [ <namespace> "vocabularies" set ] bind
|
||||||
|
|
||||||
[
|
[
|
||||||
[ "ansi-fg" | "1" ]
|
[ "ansi-fg" | "1" ]
|
||||||
|
|
Loading…
Reference in New Issue