On Tue, May 17, 2016 at 7:31 PM, Yusheng Wang <yshw...@vmware.com> wrote:

>
> From 72e885fb895d740dc62d5ea42ced764cba527b2f Mon Sep 17 00:00:00 2001
> From: Yusheng Wang <yshw...@vmware.com>
> Date: Tue, 17 May 2016 07:58:35 +0800
> Subject: [PATCH] OVN: datalog man page
>
> Signed-off-by: Yusheng Wang <yshw...@vmware.com>
>
> ---
>

Hi Yusheng,

After listening to the podcast that you and Teemu did with Ben [1], I spent
a little time educating
myself on datalog, so I can better appreciate the work you did in this doc.
The wiki page
on datalog [2] is fine but not very rich. The datalog pages returned by
google [3] were, like Teemu
said in the blog, pretty grandious. With that, I had a little hard time
finding something that was
inline with NiciraLog (nlog). If you happen to know of any public online
doc on that realm,
it would be nice to make a reference to it in the commit message of this
patchset.

Not all that relevant, but I found pyDatalog [4] to be useful in wrapping
my head of how this
technology is used. Any tools like that, or maybe a pointer to
"Test_interactive" will be a good
asset to help folks getting their feet wet.

More comments/suggestions below. I goes w/out saying but, please do ignore
anything in
my feedback that is not useful.


[1]: http://ovsorbit.benpfaff.org/#e5
[2]: https://en.wikipedia.org/wiki/Datalog
[3]: http://bfy.tw/65yd
[4]: https://sites.google.com/site/pydatalog/


<snip>


> diff --git a/ovn/lib/ovn-datalog.7.xml b/ovn/lib/ovn-datalog.7.xml
> new file mode 100644
> index 0000000..677ca0b
> --- /dev/null
> +++ b/ovn/lib/ovn-datalog.7.xml
> @@ -0,0 +1,491 @@
> +<?xml version="1.0" encoding="utf-8"?>
> +<manpage program="ovn-datalog" section="7" title="ovn-datalog">
> +
> +<h1>Name</h1>
> +<p>ovn-datalog -- Open Virtual Network Datalog</p>
> +
> +<h1>Synoposis</h1>
> +<pre fixed="yes">
> +#include "datalog.h"
> +</pre>
> +
> +<pre fixed="yes">
> +void* datalog_init(const char* <var>rules</var>, void*
> <var>ext_func</var>);
> +void  datalog_free(void* <var>d</var>);
> +void  datalog_opr(void* <var>d</var>, bool <var>query</var>);
> +</pre>
> +
> +<pre fixed="yes">
> +bool  datalog_put_table(void* <var>d</var>, bool <var>is_delete</var>,
> const char* <var>name</var>);
> +void  datalog_put_field(void* <var>d</var>, void* <var>value</var>,
> int32_t <var>size</var>);
> +</pre>
> +
> +<pre fixed="yes">
> +bool  datalog_get_table(void* <var>d</var>, bool* <var>is_delete</var>,
> const char** <var>name</var>,
> +    int32_t* <var>n_tuples</var>, int32_t* <var>n_fields</var>);
> +bool  datalog_get_field(void* <var>d</var>, void** <var>value</var>,
> int32_t* <var>size</var>);
> +</pre>
> +
> +<h1>Description</h1>
> +
> +<p>
> +The datalog_init() initializes an instance of datalog engine.
> <dfn>rules</dfn>
> + indicates the datalog program. <dfn>ext_func</dfn>, which is optional,
> will
> +specify the external function of the engine.
> +</p>
> +
> +<p>
> +Each instance of engine is defined by its program, its state, and
> temporary
> +data for input and output tables. The state consists of table content of
> all
> +input tables and intermediate tables.
>

nitpick: Remove redundant 'tables', so it reads like this:

The state consists of table content of all input and intermediate tables.


> +</p>
> +
> +<p>
> +Datalog engine works in pipeline manner. Input table is constructed by
> first
> +calling the function datalog_put_table(), then followed by a serial of
> function
> +calls of datalog_put_field(). Data are streamed field by field, then
> tuple by
> +tuple. <dfn>name</dfn> indicates the name of table. <dfn>is_remove</dfn>
> +indicates whether the tuples constructed by subsequent calls of
> +datalog_put_field() are for addition or for deletion.
> +</p>
> +
>

<snip>


> +<h1>NOTES</h1>
> +<p>
> +The following sections define the syntax, semantics, and run time behavior
> +of the OVN datalog program.
> +</p>
> +
> +<h2>SYNTAX OF OVN DATALOG</h2>
> +
> +<pre fixed="yes">
> +&lt;token&gt;          ::= [_a-zA-Z][_a-zA-Z0-9]*
> +&lt;literal&gt;        ::= '[^']*'
> +</pre>
> +
> +<p>
> +Literals are enclosed with single quote and can extend to multiple lines.
> +Comments start with pound character and end in line end. Blank characters
> are
> +ignored. Tokens are case sensitive.
> +</p>
> +
> +<pre fixed="yes">
> +&lt;table name&gt;     ::= &lt;token&gt;
> +&lt;field name&gt;     ::= &lt;token&gt;
> +
> +&lt;field&gt;          ::= &lt;field name&gt; | &lt;literal&gt; | "-"
> +&lt;field list&gt;     ::= &lt;field&gt; | &lt;field list&gt; ","
> &lt;field&gt;
> +
> +&lt;table&gt;          ::= &lt;table name&gt; "(" &lt;field list&gt; ")"
> +&lt;table list&gt;     ::= &lt;table&gt; | &lt;table list&gt;
> &lt;table&gt;
> +
> +&lt;join table&gt;     ::= &lt;table&gt; ":" &lt;table list&gt;
> +&lt;union table&gt;    ::= &lt;table&gt; "&gt;" &lt;table list&gt;
> +
> +&lt;rule&gt;           ::= &lt;join table&gt; | &lt;union table&gt;
> +&lt;rule list&gt;      ::= &lt;rule&gt; | &lt;rule list&gt; ";"
> &lt;rule&gt;
> +&lt;program&gt;        ::= &lt;rule list&gt; "."
> +</pre>
> +
> +<p>
> +Example:
> +</p>
> +
> +<pre>
> +        Aa2(a) : a1(a, 'aa', -);
> +        A3(a, 'bb') : Aa2(a) a1(a, -, b) Aa2(b);
> +        A4(x, y) &gt; Aa3(x, y) a2(y, x).
> +</pre>
> +
> +<p>
> +Each tuple is an ordered set of field values. Field name is only used for
>

A tuple is an ordered set of field values.
Field list is only for


> +specifying matching criteria. All tuples from a table have the same number
> +of fields. The field "-" is called 'ignored' field.
> +</p>
> +
> +<p>
> +For each rule, the content of left side table, e.g., Aa2 in the above
> example,
> +is determined by the content of all right side tables, e.g., a1 in the
> above
> +example. Table could appear in left side at most once.
> +</p>
> +
> +<p>
> +When a table only appears in right side, it is called input table. When a
>

When a table only appears in the right side of a given rule, it is called
input table. When a


> +table only appears in left side, it is called output table. When a table
> +appears in both left side and right side, it is called intermediate table.
> +</p>
> +
>

<snip>


> +<p>
> +Join. The content of left side table is the 'join' of all right side
> +tables. Joining produces its result in 4 steps illustrated below.
>

For folks who do not know what a join operation is about, maybe refer them
to
a link like:    https://en.wikipedia.org/wiki/Join_%28SQL%29


> +</p>
> +</li>
> +</ul>
> +
> +<pre fixed="yes">
> +                                                     Step 1
> +Example:              u(a,b)       v(x,y)       u(a,b)  v(x,y)
>

Instead of v(x,y) it may be easier to understand if it was shown as v(b,c) ?

Example of a join operation:              u(a,b)       v(b,c)       u(a,b)
v(b,c)



> +                     +---+---+    +---+---+    +---+---+---+---+
> +C(a,c):              | 1 | 2 |    | 2 | 3 |    | 1 | 2 | 2 | 3 |
> +  u(a,b)             +---+---+    +---+---+    +---+---+---+---+
> +  v(b,c).            | 1 | 3 |    | 2 | 4 | =&gt; | 1 | 2 | 2 | 4 |
> +                     +---+---+    +---+---+    +---+---+---+---+
> +                                  | 3 | 3 |    | 1 | 2 | 3 | 3 |
> +                                  +---+---+    +---+---+---+---+
> +                                               | 1 | 3 | 2 | 3 |
> + Step 4        Step 3           Step 2         +---+---+---+---+
> + C(a,c)      u(a) v(y)     u(a,b)  v(x,y)      | 1 | 3 | 2 | 4 |
> ++---+---+    +---+---+    +---+---+---+---+    +---+---+---+---+
> +| 1 | 3 |    | 1 | 3 |    | 1 | 2 | 2 | 3 |    | 1 | 3 | 3 | 3 |
> ++---+---+    +---+---+    +---+---+---+---+    +---+---+---+---+
> +| 1 | 4 | &lt;= | 1 | 4 | &lt;= | 1 | 2 | 2 | 4 | &lt;=    u.b == v.x
> ++---+---+    +---+---+    +---+---+---+---+    matching criteria
> +             | 1 | 3 |    | 1 | 3 | 3 | 3 |
> +             +---+---+    +---+---+---+---+
> +</pre>
> +
> +<pre>
> +Step 1: Perform full join operation over all right side tables.
> +Step 2: Filter the result tuple set based on matching criteria.
> +Step 3: Drop the fields that do no appear in left side table.
> +Step 4: Merge duplicate tuples and reorder fields.
> +</pre>
> +
> +<p>
> +When literal appears in right side table, it indicates to only include
> +those tuples whose specified field matches the literal. When it appears
> +in left side table, that value is always provisioned on the specified
> +field.
> +</p>
> +
> +<p>
> +'Ignored' field indicates that the specified field is neither used
> +in matching criteria, nor appearing in the left side table.
> +'Ignored' field never appears in left side table.
> +</p>
>


It would be nice to have an example of a rule with join that uses
'Ignored'...



> +
> +<p>
> +The engine works in incremental computation manner, i.e., the engine only
> +accepts incremental change for a set of input tables, and it will
> +compute the incremental change of output tables. The change is in form of
> +adding tuples or deleting tuples.
> +</p>
> +
> +<p>
> +Example: assume initially,
> +</p>
> +<pre>
> +        u(a,b) contains { (1, 2), (1, 3) },
> +        v(x,y) contains { (2, 3), (1, 3) }; then
> +        C(a,c) contains { (1, 3) }
> +</pre>
> +<p>
> +If { (2, 4) } is added to v(x,y), the engine will output { (1, 4) },
> making
> +the current state of C(a,c) as { (1, 3), (1, 4) }.
> +</p>
>

It would be nice to have another example where  { (2, 4) } is added to
v(b,c)
and the increment computation is expanded as in the example above.



> +
> +<h2>METHOD OF COMPUTATION</h2>
> +<p>
> +The test case Test_interactive is an interactive tool that shows the usage
> +of the engine.
> +</p>
> +
>

This is a bit of a chicken-and-egg, but I would love to see/use
"Test_interactive" to
solidify my understanding of what you are explaining here. Only then I may
have
the ability to say something useful. ;) Still, I do get the gist of it;
just not easy to
sink in before playing with it for a while.



> +<p>
> +The following steps are performed when the engine is initialized:
> +</p>
> +<p>
>

<snip>


> +<p>
> +which could be used to reset its state.
> +</p>
> +<p>
> +External function should only be used when union and join do not suffice.
> +OVN datalog internal APIs must be used to do the computation.
> +</p>
> +</manpage>
> --
> 2.7.4
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to