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 16:04:53 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
59d63da7659507aa2af0789e8c52107fe5114c75
59d63da7
1 parent
7f28666d
replaced maps with arrays in dicts/sets
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
94 additions
and
35 deletions
libs/go/src/dicts/dicts.go
libs/go/src/dicts/sets.go
libs/go/src/dicts/dicts.go
View file @
59d63da
...
...
@@ -7,6 +7,7 @@ import (
"bytes"
"fmt"
"reflect"
"math/bits"
)
//
...
...
@@ -57,7 +58,7 @@ type DictItem struct {
}
type
Dict
struct
{
indices
map
[
uint64
]
int64
indices
[
]
int64
itemlist
[]
DictItem
used
uint64
filled
uint64
...
...
@@ -65,7 +66,7 @@ type Dict struct {
}
func
(
self
*
Dict
)
Clear
()
{
self
.
indices
=
make
(
map
[
uint64
]
int64
)
self
.
indices
=
[]
int64
{
_FREE
,
_FREE
,
_FREE
,
_FREE
,
_FREE
,
_FREE
,
_FREE
,
_FREE
}
self
.
itemlist
=
make
([]
DictItem
,
0
)
self
.
used
=
0
self
.
filled
=
0
...
...
@@ -75,14 +76,13 @@ func (self *Dict) Clear () {
type
copyfunc
func
(
interface
{})
interface
{}
func
(
self
Dict
)
Copy
(
copiers
...
copyfunc
)
Dict
{
d
:=
Dict
{
make
(
map
[
uint64
]
int64
),
d
:=
Dict
{
make
([]
int64
,
len
(
self
.
indices
)),
make
([]
DictItem
,
len
(
self
.
itemlist
)),
self
.
used
,
self
.
filled
,
self
.
keyhash
}
for
k
,
v
:=
range
self
.
indices
{
d
.
indices
[
k
]
=
v
}
copy
(
d
.
indices
,
self
.
indices
)
if
len
(
copiers
)
==
0
{
copy
(
d
.
itemlist
,
self
.
itemlist
)
}
else
if
len
(
copiers
)
==
1
{
...
...
@@ -124,16 +124,20 @@ const _PERTURB_SHIFT uint64 = 5
type
probe
struct
{
i
uint64
index
uint64
perturb
uint64
mask
uint64
}
func
first_probe
(
hashvalue
uint64
)
(
uint64
,
probe
)
{
p
:=
probe
{
hashvalue
,
hashvalue
}
func
(
self
Dict
)
first_probe
(
hashvalue
uint64
)
(
uint64
,
probe
)
{
m
:=
uint64
(
len
(
self
.
indices
))
-
1
p
:=
probe
{
hashvalue
&
m
,
hashvalue
,
hashvalue
,
m
}
return
p
.
i
,
p
}
func
(
self
*
probe
)
next
()
uint64
{
self
.
i
=
5
*
self
.
i
+
self
.
perturb
+
1
self
.
index
=
5
*
self
.
i
+
self
.
perturb
+
1
self
.
i
=
self
.
index
&
self
.
mask
self
.
perturb
>>=
_PERTURB_SHIFT
return
self
.
i
}
...
...
@@ -141,29 +145,32 @@ func (self *probe) next () uint64 {
func
(
self
Dict
)
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
self
.
filled
>=
uint64
(
len
(
self
.
indices
))
{
panic
(
"no open slot"
)
}
i
,
p
:=
self
.
first_probe
(
hashvalue
)
for
;
true
;
i
=
p
.
next
()
{
index
:=
self
.
indices
[
i
]
switch
index
{
case
_FREE
:
if
fsempty
{
return
_FREE
,
i
}
else
{
return
_DUMMY
,
freeslot
}
}
else
if
index
==
_DUMMY
{
case
_DUMMY
:
if
fsempty
{
fsempty
=
false
freeslot
=
i
}
}
else
{
default
:
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
Dict
)
Get
(
key
interface
{})
*
interface
{}
{
...
...
@@ -191,6 +198,23 @@ func (self Dict) Fetch (key interface{}, fallback interface{}) *interface{} {
}
}
func
(
self
*
Dict
)
resize
(
size
uint64
)
{
s
:=
uint64
(
1
)
<<
uint64
(
bits
.
Len64
(
size
))
self
.
indices
=
make
([]
int64
,
s
)
for
i
:=
uint64
(
0
);
i
<
s
;
i
++
{
self
.
indices
[
i
]
=
_FREE
}
for
index
,
item
:=
range
self
.
itemlist
{
for
i
,
p
:=
self
.
first_probe
(
item
.
hash
);
true
;
i
=
p
.
next
()
{
if
self
.
indices
[
i
]
==
_FREE
{
self
.
indices
[
i
]
=
int64
(
index
)
break
}
}
}
self
.
filled
=
self
.
used
}
func
(
self
*
Dict
)
Set
(
key
interface
{},
value
interface
{})
{
hashvalue
:=
Hash
(
key
)
index
,
i
:=
self
.
lookup
(
key
,
hashvalue
)
...
...
@@ -200,6 +224,9 @@ func (self *Dict) Set (key interface{}, value interface{}) {
self
.
used
++
if
index
==
_FREE
{
self
.
filled
++
if
self
.
filled
*
3
>
uint64
(
len
(
self
.
indices
))
*
2
{
self
.
resize
(
4
*
self
.
used
)
}
}
self
.
keyhash
+=
hashvalue
}
else
{
...
...
libs/go/src/dicts/sets.go
View file @
59d63da
...
...
@@ -6,6 +6,7 @@ package dicts
import
(
"bytes"
"fmt"
"math/bits"
)
//
...
...
@@ -18,7 +19,7 @@ type SetItem struct {
}
type
Set
struct
{
indices
map
[
uint64
]
int64
indices
[
]
int64
itemlist
[]
SetItem
used
uint64
filled
uint64
...
...
@@ -26,7 +27,7 @@ type Set struct {
}
func
(
self
*
Set
)
Clear
()
{
self
.
indices
=
make
(
map
[
uint64
]
int64
)
self
.
indices
=
[]
int64
{
_FREE
,
_FREE
,
_FREE
,
_FREE
,
_FREE
,
_FREE
,
_FREE
,
_FREE
}
self
.
itemlist
=
make
([]
SetItem
,
0
)
self
.
used
=
0
self
.
filled
=
0
...
...
@@ -34,12 +35,13 @@ func (self *Set) Clear () {
}
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
))
s
:=
Set
{
make
([]
int64
,
len
(
self
.
indices
)),
make
([]
SetItem
,
len
(
self
.
itemlist
)),
self
.
used
,
self
.
filled
,
self
.
keyhash
}
copy
(
s
.
indices
,
self
.
indices
)
if
len
(
copiers
)
==
0
{
copy
(
s
.
itemlist
,
self
.
itemlist
)
}
else
if
len
(
copiers
)
==
1
{
...
...
@@ -51,9 +53,6 @@ func (self Set) Copy (copiers ...copyfunc) Set {
}
else
{
panic
(
"at most one copier is allowed"
)
}
s
.
used
=
self
.
used
s
.
filled
=
self
.
filled
s
.
keyhash
=
self
.
keyhash
return
s
}
...
...
@@ -70,32 +69,46 @@ func (self Set) Len () uint64 {
return
self
.
used
}
type
sprobe
struct
{
i
uint64
perturb
uint64
}
func
(
self
Set
)
first_probe
(
hashvalue
uint64
)
(
uint64
,
probe
)
{
m
:=
uint64
(
len
(
self
.
indices
))
-
1
p
:=
probe
{
hashvalue
&
m
,
hashvalue
,
hashvalue
,
m
}
return
p
.
i
,
p
}
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
self
.
filled
>=
uint64
(
len
(
self
.
indices
))
{
panic
(
"no open slot"
)
}
i
,
p
:=
self
.
first_probe
(
hashvalue
)
for
;
true
;
i
=
p
.
next
()
{
index
:=
self
.
indices
[
i
]
switch
index
{
case
_FREE
:
if
fsempty
{
return
_FREE
,
i
}
else
{
return
_DUMMY
,
freeslot
}
}
else
if
index
==
_DUMMY
{
case
_DUMMY
:
if
fsempty
{
fsempty
=
false
freeslot
=
i
}
}
else
{
default
:
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
{}
{
...
...
@@ -115,6 +128,23 @@ func (self Set) Fetch (key interface{}, fallback interface{}) *interface{} {
}
}
func
(
self
*
Set
)
resize
(
size
uint64
)
{
s
:=
uint64
(
1
)
<<
uint64
(
bits
.
Len64
(
size
))
self
.
indices
=
make
([]
int64
,
s
)
for
i
:=
uint64
(
0
);
i
<
s
;
i
++
{
self
.
indices
[
i
]
=
_FREE
}
for
index
,
item
:=
range
self
.
itemlist
{
for
i
,
p
:=
self
.
first_probe
(
item
.
hash
);
true
;
i
=
p
.
next
()
{
if
self
.
indices
[
i
]
==
_FREE
{
self
.
indices
[
i
]
=
int64
(
index
)
break
}
}
}
self
.
filled
=
self
.
used
}
func
(
self
*
Set
)
Add
(
key
interface
{})
{
hashvalue
:=
Hash
(
key
)
index
,
i
:=
self
.
lookup
(
key
,
hashvalue
)
...
...
@@ -124,6 +154,9 @@ func (self *Set) Add (key interface{}) {
self
.
used
++
if
index
==
_FREE
{
self
.
filled
++
if
self
.
filled
*
3
>
uint64
(
len
(
self
.
indices
))
*
2
{
self
.
resize
(
4
*
self
.
used
)
}
}
self
.
keyhash
+=
hashvalue
}
else
{
...
...
@@ -148,7 +181,6 @@ func (self *Set) Del (key interface{}) {
self
.
indices
[
j
]
=
index
self
.
itemlist
[
index
]
=
lastitem
}
self
.
itemlist
=
self
.
itemlist
[
:
self
.
used
]
self
.
keyhash
-=
hashvalue
}
...
...
Please
register
or
login
to post a comment