From 02f1ee0508b76259799468a0ba216452f9fcb362 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Sun, 1 Mar 2020 18:15:43 -0800 Subject: [PATCH] Examples and Updates --- .gitignore | 2 ++ 4count.cst | 1 + README.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++ cmd/chaos/chaos.go | 25 ++++++++++++++++++++- gset.go | 4 ++++ max.sh | 3 +++ template.go | 7 ++++++ 7 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 4count.cst create mode 100644 README.md create mode 100755 max.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7bf47a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.chaos/ +.idea/ diff --git a/4count.cst b/4count.cst new file mode 100644 index 0000000..e9cdcdb --- /dev/null +++ b/4count.cst @@ -0,0 +1 @@ +{"Structures":{"1":{"Elements":{}},"2":{"Elements":{}},"3":{"Elements":{}},"4":{"Elements":{}}},"Commands":{"add1":["1"],"add2":["2"],"add3":["3"],"add4":["4"]},"LookupIn": ["1","2","3","4"],"LookupNotIn":[]} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..2095d06 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# Chaos - Distributed Structures + +Chaos is a framework for building distributed conflict-free data structures by composing G-Sets (Grow Only Sets) + +From these simple sets, more complicated objects can be made e.g. we can build a 2-Phase Set that allows us to remove elements with a simple template (`2pset.cst`) + + { + "Structures":{ + "add":{"Elements":{}}, + "remove":{"Elements":{}} + }, + "Commands":{ + "add":["add"],"remove":["remove"] + }, + "LookupIn":["add"], + "LookupNotIn":["remove"] + } + +We can also build distributed counters, e.g. a counter to synchronize 4 nodes might look like this ([`4count.cst`](4count.cst): + + { + "Structures":{ + "1":{"Elements":{}}, + "2":{"Elements":{}}, + "3":{"Elements":{}}, + "4":{"Elements":{}} + }, + "Commands":{ + "add1":["1"], + "add2":["2"], + "add3":["3"], + "add4":["4"] + }, + "LookupIn": ["1","2","3","4"], + "LookupNotIn":[] + } + +We can then use `chaos`: + + chaos new 4count counter + # Receive from 1 + chaos add1 counter 1 + # Receive from 2 + chaos add2 counter 1 + # Receive from 3 + chaos add3 counter 1 + # Receive from 4 + chaos add4 counter 1 + # Get Max Counter Value + seq 4 | xargs -I{} chaos len counter | sort -nr | head -1 + 1 + # Receive from 4 + chaos add4 counter "in reality this would be update event 2" + # Get Max Counter Value + seq 4 | xargs -I{} chaos len counter | sort -nr | head -1 + 2 \ No newline at end of file diff --git a/cmd/chaos/chaos.go b/cmd/chaos/chaos.go index 52062fd..a1d5cad 100644 --- a/cmd/chaos/chaos.go +++ b/cmd/chaos/chaos.go @@ -59,7 +59,28 @@ func cmd_lookup(args []string) { fmt.Printf("Cannot parse \"%v\"", args[0]) return } - fmt.Printf("%v", template.Lookup(args[1])) + fmt.Printf("%v\n", template.Lookup(args[1])) + } else { + fmt.Printf("Chaos structure \"%v\" does not exist\n", args[0]) + return + } + } else { + fmt.Printf("Usage: chaos lookup \n") + } +} + +func cmd_len(args []string) { + if len(args) == 2 { + path := path.Join(".", ".chaos", args[0]) + if _, err := os.Stat(path); err == nil { + data, _ := ioutil.ReadFile(path) + template := chaos.NewTemplate() + err := json.Unmarshal(data, template) + if err != nil { + fmt.Printf("Cannot parse \"%v\"", args[0]) + return + } + fmt.Printf("%v\n", template.Len(args[1])) } else { fmt.Printf("Chaos structure \"%v\" does not exist\n", args[0]) return @@ -78,6 +99,8 @@ func main() { cmd_new(os.Args[2:]) case "lookup": cmd_lookup(os.Args[2:]) + case "len": + cmd_len(os.Args[2:]) default: cmd(os.Args[1], os.Args[2:]) } diff --git a/gset.go b/gset.go index ee077a4..cca3ac2 100644 --- a/gset.go +++ b/gset.go @@ -12,6 +12,10 @@ func (gs *GSet) Add(element string) { gs.Elements[element] = true } +func (gs *GSet) Len() int { + return len(gs.Elements) +} + func (gs *GSet) Lookup(element string) bool { _, exists := gs.Elements[element] return exists diff --git a/max.sh b/max.sh new file mode 100755 index 0000000..ab246ee --- /dev/null +++ b/max.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# Find the Max Counter Value in an n-Count structure +seq $2 | xargs -I{} chaos len $1 {} | sort -nr | head -1 \ No newline at end of file diff --git a/template.go b/template.go index 72e451a..73f3398 100644 --- a/template.go +++ b/template.go @@ -28,6 +28,13 @@ func (t *Template) ExecCmd(cmd string, element string) { } } +func (t *Template) Len(structure string) int{ + if _,exists := t.Structures[structure]; exists { + return t.Structures[structure].Len() + } + return 0 +} + func (t *Template) Lookup(element string) bool { for _, structure := range t.LookupIn { if t.Structures[structure].Lookup(element) == false {