BeepBeep 3: A declarative event stream query engine (EDOC 2015)
A "Do-It-Yourself" Specification Language with BeepBeep 3 (Talk @ Dagstuhl 2017)
-
Upload
sylvain-halle -
Category
Technology
-
view
24 -
download
0
Transcript of A "Do-It-Yourself" Specification Language with BeepBeep 3 (Talk @ Dagstuhl 2017)
EventsEvents are arbitrary dataelements produced in a sequencecalled a stream. Any Java object canbe used as an event.
23
4
π abc
3 8 a3 8 a
2 6 c
+⊇?
<a><a><a>
Numbers Strings XMLdocuments
Booleans
Tuples Functions Sets Plots
⊇?
34
FunctionsFunctions
1:1function
2:1function
6
6 0:1function
transform events into other events.
FunctionApplies a function toevery input event
CumulativeComputes theprogressive "sum" ofall input events
TrimRemoves the first ninput events
DecimateOutputs everyn-th event
GroupEncloses a group ofconnected processors
ForkDuplicates a streaminto multiple copies
SliceSplits a stram into multiplesub-streams
WindowApplies a function toa sliding window ofn events
ProcessorsProcessors are simple computingunits that transform input streams into outputstreams. BeepBeep's core is made of a handful ofgeneral purpose processors.
f
Σ f
n
FilterA first, Boolean stream, decides if each event of a second stream should be output
{
f
PipingPiping the output of processors to theinput of others creates a chain that producesthe desired computation.
Any output can be connected to any input,as long as they have the same type. Many typescan occur in the same chain. The final outputof the chain can be of any type, too.
Fork f = new Fork(2);FunctionProcessor sum =new FunctionProcessor(Addition.instance);
CountDecimate decimate = new CountDecimate(n);Connector.connect(fork, LEFT, sum, LEFT). connect(fork, RIGHT, decimate, INPUT). connect(decimate, OUTPUT, sum, RIGHT);Pullable p = sum.getOutputPullable(OUTPUT);while (p.hasNext() != NextStatus.NO) {Object o = p.next();
. ..}
n
→
→
→
+
→
→
→
→
→
f1 LOC per vertex1 LOC per edge
They can contain arbitrary Java code, memberfields, etc. "What happens in the box remains inthe box."
CustomCustom processors and functions canbe created by inheriting from the basic Processorand Function objects provided by BeepBeep.
class Counter extends UniformProcessor {
int cnt = 0;
public Counter() { super(1,1); }
public void compute(Object[] in, Queue<> out) { cnt++; out.add(new Object[]{cnt}); }}
PalettesPalettes are groups of functions andprocessors centered around a particular use case.They represent a simple, but powerful way ofextending BeepBeep to a user's needs. A few ofthe palettes available so far:
XML eventsPlotting
Finite-state machines
Temporal logicSignal processingVarious log formats
Networking
...create your own
→
A/a/b//character[status=Walker]/id/text()
→ p1
→
A
→ p2
→ →→
→
/a/b
→
→→
3
→
→
→
<?
→
→
→
→→
→
→
→
f1
f2
→
→ →
→
→
→
→
//character[status=Blocker]/id/text()
→
→
**
*
*
Create Auction=?0
@
Last PriceDays
0:=
3@Max. Days :=Min. Price 2@:=
Days :=Days 1
+
End of Day=?
0
@
>
<?Days
Last Price
2
@:=
Bid=?
0
@
>
Min. Price<?
2
@
Last Price>?
2
@
Bid=?
0
@
>
Last Price>?
2
@
Days :=Days 1
+
End of Day=?
0
@
Max. Days
→
End of Day *1@*
→→→ →
*Sold
=?0
@
Days
Days
+ | |.÷ →
→→
→
SELECT@0 AS x
@1 AS y
→→
+
0
Σ→ →1
→
→→
∅ +=Σ
BeepBeep provides a runtime parsercalled Bullwinkle.
It comes with no grammar!
You can define your own, alongwith a parse tree visitor, tocreate your own BeepBeepdomain-specific language.
<Processor> := <CountDecimate> | <CumulativeSum> | <Mutator> | <QueueSource> ;
<CountDecimate> := Take one every <Number> from <Processor> ;
<CumulativeSum> := Accumulate <Processor> ;
<Mutator> := Turn <Processor> into <Number> ;
<QueueSource> := [ <Number> , <Number> , <Number> ] ;
<Number> := ^[\\d]+;
Step 1Step 1Define a grammar in BNF.
class MyInterpreter extends ExpressionParser<Processor> {
public void doCountDecimate(Stack<Object> stack) { Processor p = (Processor) stack.pop(); stack.pop(); // from Constant n = (Constant) stack.pop(); stack.pop(); // every stack.pop(); // one stack.pop(); // Take CountDecimate dec = new CountDecimate( ((Number) n.getValue()).intValue()); Connector.connect(p, dec); m_builtObject.addProcessor(dec); stack.push(dec); } ...}
Step 2Step 2Create an ExpressionParser, with a methoddoXXX for every non-terminal symbol xxx youwant to handle.
MyInterpreter my_int = new MyInterpreter();Processor proc = my_int.parse( "Take one every 2 from The sum of [3, 4, 6]");
SomeOtherProcessor op = ..Connector.connect(proc, op);...
Step 3Step 3Enjoy!
3 4
Σ0
+6
2
Can be used to pipe together anyprocessor and/or function
...including those you define yourself
...(that may contain arbitrary Java code)
...and only those you want to include
...from any existing palette
...using a syntax you choose
An easy way to create simplelanguages that do complex things
https://liflab.github.io/beepbeep-3 .../beepbeep-3-examples