Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Franck Pommereau
/
zinc
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Franck Pommereau
2018-04-05 11:13:35 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
db33647f73ea35fbc50d7b0f6f6c58078c1e7465
db33647f
1 parent
4c6da427
set implementation use less memory
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
298 additions
and
59 deletions
libs/go/src/dicts/dicts.go
libs/go/src/dicts/hash.go
libs/go/src/dicts/sets.go
libs/go/src/zn/multisets.go
libs/go/src/zn/sets.go
libs/go/src/dicts/dicts.go
View file @
db33647
...
...
@@ -33,13 +33,13 @@ func Hash (value interface{}) uint64 {
// compare any values
//
type
e
quatable
interface
{
type
E
quatable
interface
{
Eq
(
interface
{})
bool
}
func
Eq
(
a
,
b
interface
{})
bool
{
i
,
ok
:=
a
.
(
e
quatable
)
i
,
ok
:=
a
.
(
E
quatable
)
if
ok
{
return
i
.
Eq
(
b
)
}
...
...
@@ -50,7 +50,7 @@ func Eq (a, b interface{}) bool {
// dict type
//
type
Item
struct
{
type
Dict
Item
struct
{
Key
*
interface
{}
Value
*
interface
{}
hash
uint64
...
...
@@ -58,7 +58,7 @@ type Item struct {
type
Dict
struct
{
indices
map
[
uint64
]
int64
itemlist
[]
Item
itemlist
[]
Dict
Item
used
uint64
filled
uint64
keyhash
uint64
...
...
@@ -66,7 +66,7 @@ type Dict struct {
func
(
self
*
Dict
)
Clear
()
{
self
.
indices
=
make
(
map
[
uint64
]
int64
)
self
.
itemlist
=
make
([]
Item
,
0
)
self
.
itemlist
=
make
([]
Dict
Item
,
0
)
self
.
used
=
0
self
.
filled
=
0
self
.
keyhash
=
0
...
...
@@ -80,14 +80,14 @@ func (self Dict) Copy (copiers ...copyfunc) Dict {
for
k
,
v
:=
range
self
.
indices
{
d
.
indices
[
k
]
=
v
}
d
.
itemlist
=
make
([]
Item
,
len
(
self
.
itemlist
))
d
.
itemlist
=
make
([]
Dict
Item
,
len
(
self
.
itemlist
))
if
len
(
copiers
)
==
0
{
copy
(
d
.
itemlist
,
self
.
itemlist
)
}
else
if
len
(
copiers
)
==
1
{
cpk
:=
copiers
[
0
]
for
index
,
item
:=
range
self
.
itemlist
{
k
:=
cpk
(
*
(
item
.
Key
))
d
.
itemlist
[
index
]
=
Item
{
&
k
,
item
.
Value
,
item
.
hash
}
d
.
itemlist
[
index
]
=
Dict
Item
{
&
k
,
item
.
Value
,
item
.
hash
}
}
}
else
if
len
(
copiers
)
==
2
{
cpk
:=
copiers
[
0
]
...
...
@@ -95,7 +95,7 @@ func (self Dict) Copy (copiers ...copyfunc) Dict {
for
index
,
item
:=
range
self
.
itemlist
{
k
:=
cpk
(
*
(
item
.
Key
))
v
:=
cpv
(
*
(
item
.
Value
))
d
.
itemlist
[
index
]
=
Item
{
&
k
,
&
v
,
item
.
hash
}
d
.
itemlist
[
index
]
=
Dict
Item
{
&
k
,
&
v
,
item
.
hash
}
}
}
else
{
panic
(
"at most two copiers are allowed"
)
...
...
@@ -106,7 +106,7 @@ func (self Dict) Copy (copiers ...copyfunc) Dict {
return
d
}
func
MakeDict
(
items
...
Item
)
Dict
{
func
MakeDict
(
items
...
Dict
Item
)
Dict
{
d
:=
Dict
{}
d
.
Clear
()
for
_
,
i
:=
range
items
{
...
...
@@ -173,7 +173,7 @@ func (self Dict) Get (key interface{}) *interface{} {
return
self
.
itemlist
[
index
]
.
Value
}
func
(
self
Dict
)
GetItem
(
key
interface
{})
*
Item
{
func
(
self
Dict
)
GetItem
(
key
interface
{})
*
Dict
Item
{
index
,
_
:=
self
.
lookup
(
key
,
Hash
(
key
))
if
index
<
0
{
return
nil
...
...
@@ -195,14 +195,14 @@ func (self *Dict) Set (key interface{}, value interface{}) {
index
,
i
:=
self
.
lookup
(
key
,
hashvalue
)
if
index
<
0
{
self
.
indices
[
i
]
=
int64
(
self
.
used
)
self
.
itemlist
=
append
(
self
.
itemlist
,
Item
{
&
key
,
&
value
,
hashvalue
})
self
.
itemlist
=
append
(
self
.
itemlist
,
Dict
Item
{
&
key
,
&
value
,
hashvalue
})
self
.
used
++
if
index
==
_FREE
{
self
.
filled
++
}
self
.
keyhash
+=
hashvalue
}
else
{
self
.
itemlist
[
index
]
=
Item
{
&
key
,
&
value
,
hashvalue
}
self
.
itemlist
[
index
]
=
Dict
Item
{
&
key
,
&
value
,
hashvalue
}
}
}
...
...
@@ -232,7 +232,7 @@ type DictIterator struct {
d
*
Dict
}
func
(
self
*
DictIterator
)
Next
()
*
Item
{
func
(
self
*
DictIterator
)
Next
()
*
Dict
Item
{
self
.
i
++
if
self
.
i
>=
self
.
d
.
used
{
return
nil
...
...
@@ -241,7 +241,7 @@ func (self *DictIterator) Next () *Item {
}
}
func
(
self
Dict
)
Iter
()
(
DictIterator
,
*
Item
)
{
func
(
self
Dict
)
Iter
()
(
DictIterator
,
*
Dict
Item
)
{
it
:=
DictIterator
{
0
,
&
self
}
if
self
.
used
==
0
{
return
it
,
nil
...
...
@@ -255,7 +255,7 @@ func (self Dict) Has (key interface{}) bool {
return
index
>=
0
}
func
(
self
*
Dict
)
Pop
()
Item
{
func
(
self
*
Dict
)
Pop
()
Dict
Item
{
if
self
.
used
==
0
{
panic
(
"cannot Pop from empty Dict"
)
}
...
...
@@ -313,8 +313,8 @@ func (self Dict) String () string {
return
buf
.
String
()
}
func
(
self
Item
)
String
()
string
{
return
fmt
.
Sprintf
(
"Item{%s}"
,
func
(
self
Dict
Item
)
String
()
string
{
return
fmt
.
Sprintf
(
"
Dict
Item{%s}"
,
fmt
.
Sprintf
(
"%#v, %#v, %#v"
,
fmt
.
Sprint
(
*
(
self
.
Key
)),
fmt
.
Sprint
(
*
(
self
.
Value
)),
...
...
libs/go/src/dicts/hash.go
View file @
db33647
...
...
@@ -143,14 +143,14 @@ type visitOpts struct {
StructField
string
}
type
h
ashable
interface
{
type
H
ashable
interface
{
Hash
()
uint64
}
func
(
w
*
walker
)
visit
(
v
reflect
.
Value
,
opts
*
visitOpts
)
(
uint64
,
error
)
{
// Call method Hash() is any
i
,
ok
:=
v
.
Interface
()
.
(
h
ashable
)
i
,
ok
:=
v
.
Interface
()
.
(
H
ashable
)
if
ok
{
return
i
.
Hash
(),
nil
}
...
...
libs/go/src/dicts/sets.go
0 → 100644
View file @
db33647
// Python3 dicts ported to Go, inspired from a Python version at
// https://code.activestate.com/recipes/578375/
package
dicts
import
(
"bytes"
"fmt"
)
//
// set type
//
type
SetItem
struct
{
Key
*
interface
{}
hash
uint64
}
type
Set
struct
{
indices
map
[
uint64
]
int64
itemlist
[]
SetItem
used
uint64
filled
uint64
keyhash
uint64
}
func
(
self
*
Set
)
Clear
()
{
self
.
indices
=
make
(
map
[
uint64
]
int64
)
self
.
itemlist
=
make
([]
SetItem
,
0
)
self
.
used
=
0
self
.
filled
=
0
self
.
keyhash
=
0
}
func
(
self
Set
)
Copy
(
copiers
...
copyfunc
)
Set
{
s
:=
Set
{}
s
.
indices
=
make
(
map
[
uint64
]
int64
)
for
k
,
v
:=
range
self
.
indices
{
s
.
indices
[
k
]
=
v
}
s
.
itemlist
=
make
([]
SetItem
,
len
(
self
.
itemlist
))
if
len
(
copiers
)
==
0
{
copy
(
s
.
itemlist
,
self
.
itemlist
)
}
else
if
len
(
copiers
)
==
1
{
cpk
:=
copiers
[
0
]
for
index
,
item
:=
range
self
.
itemlist
{
k
:=
cpk
(
*
(
item
.
Key
))
s
.
itemlist
[
index
]
=
SetItem
{
&
k
,
item
.
hash
}
}
}
else
{
panic
(
"at most one copier is allowed"
)
}
s
.
used
=
self
.
used
s
.
filled
=
self
.
filled
s
.
keyhash
=
self
.
keyhash
return
s
}
func
MakeSet
(
items
...
interface
{})
Set
{
s
:=
Set
{}
s
.
Clear
()
for
_
,
i
:=
range
items
{
s
.
Add
(
i
)
}
return
s
}
func
(
self
Set
)
Len
()
uint64
{
return
self
.
used
}
func
(
self
Set
)
lookup
(
key
interface
{},
hashvalue
uint64
)
(
int64
,
uint64
)
{
var
freeslot
uint64
var
fsempty
bool
=
true
for
i
,
p
:=
first_probe
(
hashvalue
);
true
;
i
=
p
.
next
()
{
index
,
found
:=
self
.
indices
[
i
]
if
!
found
{
if
fsempty
{
return
_FREE
,
i
}
else
{
return
_DUMMY
,
freeslot
}
}
else
if
index
==
_DUMMY
{
if
fsempty
{
fsempty
=
false
freeslot
=
i
}
}
else
{
item
:=
self
.
itemlist
[
index
]
if
item
.
Key
==
&
key
||
item
.
hash
==
hashvalue
&&
Eq
(
*
(
item
.
Key
),
key
)
{
return
index
,
i
}
}
}
// never reached
panic
(
"unreachable code has been reached"
)
return
0
,
0
}
func
(
self
Set
)
Get
(
key
interface
{})
*
interface
{}
{
index
,
_
:=
self
.
lookup
(
key
,
Hash
(
key
))
if
index
<
0
{
return
nil
}
return
self
.
itemlist
[
index
]
.
Key
}
func
(
self
Set
)
Fetch
(
key
interface
{},
fallback
interface
{})
*
interface
{}
{
index
,
_
:=
self
.
lookup
(
key
,
Hash
(
key
))
if
index
<
0
{
return
&
fallback
}
else
{
return
self
.
itemlist
[
index
]
.
Key
}
}
func
(
self
*
Set
)
Add
(
key
interface
{})
{
hashvalue
:=
Hash
(
key
)
index
,
i
:=
self
.
lookup
(
key
,
hashvalue
)
if
index
<
0
{
self
.
indices
[
i
]
=
int64
(
self
.
used
)
self
.
itemlist
=
append
(
self
.
itemlist
,
SetItem
{
&
key
,
hashvalue
})
self
.
used
++
if
index
==
_FREE
{
self
.
filled
++
}
self
.
keyhash
+=
hashvalue
}
else
{
self
.
itemlist
[
index
]
=
SetItem
{
&
key
,
hashvalue
}
}
}
func
(
self
*
Set
)
Del
(
key
interface
{})
{
hashvalue
:=
Hash
(
key
)
index
,
i
:=
self
.
lookup
(
key
,
hashvalue
)
if
index
<
0
{
return
}
self
.
indices
[
i
]
=
_DUMMY
self
.
used
--
if
uint64
(
index
)
!=
self
.
used
{
lastitem
:=
self
.
itemlist
[
self
.
used
]
lastindex
,
j
:=
self
.
lookup
(
*
(
lastitem
.
Key
),
lastitem
.
hash
)
if
lastindex
<
0
||
i
==
j
{
panic
(
"inconsistent Set internal state"
)
}
self
.
indices
[
j
]
=
index
self
.
itemlist
[
index
]
=
lastitem
}
self
.
itemlist
=
self
.
itemlist
[
:
self
.
used
]
self
.
keyhash
-=
hashvalue
}
type
SetIterator
struct
{
i
uint64
s
*
Set
}
func
(
self
*
SetIterator
)
Next
()
*
SetItem
{
self
.
i
++
if
self
.
i
>=
self
.
s
.
used
{
return
nil
}
else
{
return
&
(
self
.
s
.
itemlist
[
self
.
i
])
}
}
func
(
self
Set
)
Iter
()
(
SetIterator
,
*
SetItem
)
{
it
:=
SetIterator
{
0
,
&
self
}
if
self
.
used
==
0
{
return
it
,
nil
}
else
{
return
it
,
&
(
self
.
itemlist
[
0
])
}
}
func
(
self
Set
)
Has
(
key
interface
{})
bool
{
index
,
_
:=
self
.
lookup
(
key
,
Hash
(
key
))
return
index
>=
0
}
func
(
self
*
Set
)
Pop
()
SetItem
{
if
self
.
used
==
0
{
panic
(
"cannot Pop from empty Set"
)
}
item
:=
self
.
itemlist
[
self
.
used
-
1
]
self
.
Del
(
*
(
item
.
Key
))
self
.
keyhash
-=
item
.
hash
return
item
}
func
(
self
Set
)
Hash
()
uint64
{
return
self
.
keyhash
}
func
(
self
Set
)
Eq
(
other
interface
{})
bool
{
s
,
ok
:=
other
.
(
Set
)
if
ok
{
if
self
.
Len
()
!=
s
.
Len
()
{
return
false
}
else
if
self
.
keyhash
!=
s
.
keyhash
{
return
false
}
for
i
:=
uint64
(
0
);
i
<
self
.
used
;
i
++
{
value
:=
s
.
Get
(
*
(
self
.
itemlist
[
i
]
.
Key
))
if
value
==
nil
{
return
false
}
}
return
true
}
else
{
return
false
}
}
//
//
//
func
(
self
Set
)
String
()
string
{
buf
:=
bytes
.
NewBufferString
(
"{"
)
for
i
:=
uint64
(
0
);
i
<
self
.
used
;
i
++
{
if
i
>
0
{
buf
.
WriteString
(
", "
)
}
buf
.
WriteString
(
fmt
.
Sprintf
(
"%#v"
,
*
(
self
.
itemlist
[
i
]
.
Key
)))
}
buf
.
WriteString
(
"}"
)
return
buf
.
String
()
}
func
(
self
SetItem
)
String
()
string
{
return
fmt
.
Sprintf
(
"SetItem{%s}"
,
fmt
.
Sprintf
(
"%#v, %#v"
,
fmt
.
Sprint
(
*
(
self
.
Key
)),
self
.
hash
))
}
func
(
self
Set
)
ShowStructure
()
{
for
i
:=
0
;
i
<
50
;
i
++
{
fmt
.
Print
(
"="
)
}
fmt
.
Println
()
fmt
.
Println
(
self
)
fmt
.
Println
(
"Indices:"
,
self
.
indices
)
fmt
.
Println
(
"Items:"
)
for
i
:=
uint64
(
0
);
i
<
self
.
used
;
i
++
{
fmt
.
Printf
(
" [%d] %s
\n
"
,
i
,
self
.
itemlist
[
i
])
}
for
i
:=
0
;
i
<
50
;
i
++
{
fmt
.
Print
(
"-"
)
}
fmt
.
Println
()
}
libs/go/src/zn/multisets.go
View file @
db33647
...
...
@@ -142,7 +142,7 @@ type MsetIterator struct {
iter
dicts
.
DictIterator
dup
bool
count
uint64
current
*
dicts
.
Item
current
*
dicts
.
Dict
Item
}
func
(
self
*
MsetIterator
)
Next
()
*
interface
{}
{
...
...
libs/go/src/zn/sets.go
View file @
db33647
...
...
@@ -3,23 +3,7 @@ package zn
import
"dicts"
type
Set
struct
{
d
*
dicts
.
Dict
}
type
_z
struct
{
}
func
(
self
_z
)
Hash
()
uint64
{
return
8806599771745799646
}
func
(
self
_z
)
Eq
(
other
interface
{})
bool
{
_
,
ok
:=
other
.
(
_z
)
if
ok
{
return
true
}
else
{
return
false
}
s
*
dicts
.
Set
}
//*** a := zn.MakeMarking()
...
...
@@ -30,19 +14,19 @@ func (self _z) Eq (other interface{}) bool {
//*** c.Set("p3", 3)
func
MakeSet
(
markings
...
Marking
)
Set
{
dict
:=
dicts
.
MakeDic
t
()
set
:=
dicts
.
MakeSe
t
()
for
_
,
m
:=
range
markings
{
dict
.
Set
(
m
,
_z
{}
)
set
.
Add
(
m
)
}
return
Set
{
&
dic
t
}
return
Set
{
&
se
t
}
}
func
(
self
Set
)
Empty
()
bool
{
return
self
.
d
.
Len
()
==
0
return
self
.
s
.
Len
()
==
0
}
func
(
self
Set
)
NotEmpty
()
bool
{
return
self
.
d
.
Len
()
>
0
return
self
.
s
.
Len
()
>
0
}
//+++ zn.MakeSet().Empty()
...
...
@@ -51,7 +35,7 @@ func (self Set) NotEmpty () bool {
//+++ zn.MakeSet(a).NotEmpty()
func
(
self
Set
)
Len
()
uint64
{
return
self
.
d
.
Len
()
return
self
.
s
.
Len
()
}
//+++ zn.MakeSet().Len() == 0
...
...
@@ -59,7 +43,7 @@ func (self Set) Len () uint64 {
//+++ zn.MakeSet(a, a).Len() == 1
func
(
self
*
Set
)
Add
(
m
Marking
)
{
self
.
d
.
Set
(
m
,
_z
{}
)
self
.
s
.
Add
(
m
)
}
//### s := zn.MakeSet(a, b)
...
...
@@ -73,22 +57,22 @@ func (self *Set) Add (m Marking) {
//=== 3
func
(
self
Set
)
Get
(
m
Marking
)
(
bool
,
Marking
)
{
i
:=
self
.
d
.
GetItem
(
m
)
if
i
==
nil
{
return
false
,
Ma
rking
{
nil
,
-
1
}
k
:=
self
.
s
.
Get
(
m
)
if
k
==
nil
{
return
false
,
Ma
keMarking
()
}
else
{
return
true
,
(
*
(
i
.
Key
)
)
.
(
Marking
)
return
true
,
(
*
k
)
.
(
Marking
)
}
}
//### x := a.Copy()
//... x.
SetId(42)
//... x.
Id = 42
//... s := zn.MakeSet(x, b)
//... s.Get(a)
//=== true [42] {"p1": [1]}
func
(
self
Set
)
Has
(
m
Marking
)
bool
{
return
self
.
d
.
Has
(
m
)
return
self
.
s
.
Has
(
m
)
}
//+++ zn.MakeSet(a, b).Has(a)
...
...
@@ -96,7 +80,7 @@ func (self Set) Has (m Marking) bool {
//--- zn.MakeSet(a, b).Has(c)
type
SetIterator
struct
{
i
dicts
.
Dic
tIterator
i
dicts
.
Se
tIterator
}
func
(
self
*
SetIterator
)
Next
()
*
Marking
{
...
...
@@ -110,7 +94,7 @@ func (self *SetIterator) Next () *Marking {
}
func
(
self
Set
)
Iter
()
(
SetIterator
,
*
Marking
)
{
i
,
f
:=
self
.
d
.
Iter
()
i
,
f
:=
self
.
s
.
Iter
()
if
f
==
nil
{
return
SetIterator
{
i
},
nil
}
else
{
...
...
@@ -119,12 +103,12 @@ func (self Set) Iter () (SetIterator, *Marking) {
}
}
//### a.
SetId(1)
//... b.
SetId(2)
//... c.
SetId(3)
//### a.
Id = 1
//... b.
Id = 2
//... c.
Id = 3
//... s := zn.MakeSet(a, b, c)
//... for i, m := s.Iter(); m != nil; m = i.Next() { fmt.Println(
*m
) }
//... for i, m := s.Iter(); m != nil; m = i.Next() { fmt.Println(
(*m).Id
) }
//... nil
//===
[1] {"p1": [1]}
//===
[2] {"p1": [1], "p2": [2]}
//===
[3] {"p1": [1], "p2": [2], "p3": [3]}
//===
1
//===
2
//===
3
...
...
Please
register
or
login
to post a comment