Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
24930939
Commit
24930939
authored
Sep 29, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
ed2de0de
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
106 additions
and
663 deletions
+106
-663
wcfs/internal/xbtree/blib/rangemap.go.in
wcfs/internal/xbtree/blib/rangemap.go.in
+34
-77
wcfs/internal/xbtree/blib/rangemap_test.go
wcfs/internal/xbtree/blib/rangemap_test.go
+2
-4
wcfs/internal/xbtree/blib/rangeset.go
wcfs/internal/xbtree/blib/rangeset.go
+2
-2
wcfs/internal/xbtree/blib/rangeset.go.orig
wcfs/internal/xbtree/blib/rangeset.go.orig
+0
-426
wcfs/internal/xbtree/blib/zrangemap_str.go
wcfs/internal/xbtree/blib/zrangemap_str.go
+34
-77
wcfs/internal/xbtree/blib/zrangemap_void.go
wcfs/internal/xbtree/blib/zrangemap_void.go
+34
-77
No files found.
wcfs/internal/xbtree/blib/rangemap.go.in
View file @
24930939
...
...
@@ -25,8 +25,8 @@ import (
"sort"
)
const
traceRangeMap
=
tru
e
const
debugRangeMap
=
tru
e
const
traceRangeMap
=
fals
e
const
debugRangeMap
=
fals
e
//
RangedMap
is
Key
->
VALUE
map
with
adjacent
keys
mapped
to
the
same
value
coalesced
into
Ranges
.
//
...
...
@@ -116,7 +116,8 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
defer
M
.
verify
()
//
clear
range
for
r
and
insert
new
entry
//
TODO
optimize
for
set
case
(
just
merge
all
covered
entries
into
one
)
//
TODO
optimize
for
set
case
(
just
merge
all
covered
entries
into
one
-
//
-
see
commented
AddRange
vvv
)
i
:=
M
.
delRange
(
r
)
vInsert
(&
M
.
entryv
,
i
,
e
)
debugfRMap
(
"
\t
insert %s
\t
-> %s
\n
"
,
e
,
M
)
...
...
@@ -144,18 +145,18 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
//
done
/*
/*
how
it
was
for
just
set
:
//
find
first
ilo
:
r
.
Lo
<
[
ilo
].
hi
l
:=
len
(
M
.
entry
v
)
l
:=
len
(
S
.
range
v
)
ilo
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
r
.
Lo
<=
M
.
entry
v
[
i
].
Hi_
return
r
.
Lo
<=
S
.
range
v
[
i
].
Hi_
})
debugfR
Map
(
"
\t
ilo: %d
\n
"
,
ilo
)
debugfR
Set
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
//
not
found
M
.
entryv
=
append
(
M
.
entryv
,
e
)
S
.
rangev
=
append
(
S
.
rangev
,
r
)
l
++
debugfR
Map
(
"
\t
append %s
\t
-> %s
\n
"
,
e
,
M
)
debugfR
Set
(
"
\t
append %s
\t
-> %s
\n
"
,
r
,
S
)
}
//
find
last
jhi
:
[
jhi
].
Lo
<
r
.
hi
...
...
@@ -164,97 +165,53 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
if
jhi
==
l
{
break
}
if
M
.
entry
v
[
jhi
].
Lo
<=
r
.
Hi_
{
if
S
.
range
v
[
jhi
].
Lo
<=
r
.
Hi_
{
continue
}
break
}
debugfRMap
(
"
\t
jhi: %d
\n
"
,
jhi
)
//
[
ilo
+
1
:
jhi
-
1
]
should
be
deleted
if
(
jhi
-
ilo
)
>
2
{
vDeleteSlice
(&
M
.
entryv
,
ilo
+
1
,
jhi
-
1
)
debugfRMap
(
"
\t
delete M[%d:%d]
\t
-> %s
\n
"
,
ilo
+
1
,
jhi
-
1
,
M
)
}
//
if
r
was
overlapping
with
sole
region
->
presplit
it
TODO
only
if
!vsame
x
:=
M
.
entryv
[
ilo
]
if
jhi
-
ilo
==
1
&&
x
.
Lo
<
r
.
Lo
&&
r
.
Hi_
<
x
.
Hi_
{
vInsert
(&
M
.
entryv
,
ilo
,
x
)
jhi
++
debugfRMap
(
"
\t
presplit copy %s
\t
-> %s
\n
"
,
x
,
M
)
}
jhi
=
-
1
//
no
longer
valid
//
create
new
entry
//
now
it
is
vInsert
(&
M
.
entryv
,
ilo
+
1
,
e
)
//
[
ilo
]
is
now
to
the
left
//
[
ilo
]
and
[
jhi
-
1
]
overlap
with
[
r
.
lo
,
r
.
hi
)
-
XXX
if
jhi
-
ilo
==
1
{
x
:=
M
.
entryv
[
ilo
]
if
x
.
Value
!= v {
vInsert
(&
M
.
entryv
,
ilo
,
x
)
jhi
++
debugfRMap
(
"
\t
presplit copy %s
\t
-> %s
\n
"
,
x
,
M
)
}
else
{
//
XXX
extend
left
/
right
if
needed
XXX
here
?
}
}
if
xl
.
Value
!= v {
}
debugfRSet
(
"
\t
jhi: %d
\n
"
,
jhi
)
//
entries
in
[
ilo
:
jhi
)
∈
[
r
.
Lo
,
r
.
hi
)
and
should
be
merged
into
one
//
FIXME
check
different
values
if
(
jhi
-
ilo
)
>
1
{
lo
:=
M
.
entry
v
[
ilo
].
Lo
hi_
:=
M
.
entry
v
[
jhi
-
1
].
Hi_
vReplaceSlice
(&
M
.
entryv
,
ilo
,
jhi
,
RangedMapEntry
{
v
,
KeyRange
{
lo
,
hi_
}
})
debugfR
Map
(
"
\t
merge M[%d:%d]
\t
-> %s
\n
"
,
ilo
,
jhi
,
M
)
lo
:=
S
.
range
v
[
ilo
].
Lo
hi_
:=
S
.
range
v
[
jhi
-
1
].
Hi_
vReplaceSlice
(&
S
.
rangev
,
ilo
,
jhi
,
KeyRange
{
lo
,
hi_
})
debugfR
Set
(
"
\t
merge S[%d:%d]
\t
-> %s
\n
"
,
ilo
,
jhi
,
S
)
}
jhi
=
-
1
//
no
longer
valid
//
if
[
r
.
lo
,
r
.
hi
)
was
outside
of
any
entry
-
create
new
entry
if
r
.
Hi_
<
M
.
entry
v
[
ilo
].
Lo
{
vInsert
(&
M
.
entryv
,
ilo
,
e
)
debugfR
Map
(
"
\t
insert %s
\t
-> %s
\n
"
,
e
,
M
)
if
r
.
Hi_
<
S
.
range
v
[
ilo
].
Lo
{
vInsert
(&
S
.
rangev
,
ilo
,
r
)
debugfR
Set
(
"
\t
insert %s
\t
-> %s
\n
"
,
r
,
S
)
}
//
now
we
have
covered
entries
merged
as
needed
into
[
ilo
]
//
extend
this
entry
if
r
coverage
is
wider
if
r
.
Lo
<
M
.
entry
v
[
ilo
].
Lo
{
M
.
entry
v
[
ilo
].
Lo
=
r
.
Lo
debugfR
Map
(
"
\t
extend left
\t
-> %s
\n
"
,
M
)
if
r
.
Lo
<
S
.
range
v
[
ilo
].
Lo
{
S
.
range
v
[
ilo
].
Lo
=
r
.
Lo
debugfR
Set
(
"
\t
extend left
\t
-> %s
\n
"
,
S
)
}
if
r
.
Hi_
>
M
.
entry
v
[
ilo
].
Hi_
{
M
.
entry
v
[
ilo
].
Hi_
=
r
.
Hi_
debugfR
Map
(
"
\t
extend right
\t
-> %s
\n
"
,
M
)
if
r
.
Hi_
>
S
.
range
v
[
ilo
].
Hi_
{
S
.
range
v
[
ilo
].
Hi_
=
r
.
Hi_
debugfR
Set
(
"
\t
extend right
\t
-> %s
\n
"
,
S
)
}
//
and
check
if
we
should
merge
it
with
right
/
left
neighbours
if
ilo
+
1
<
len
(
M
.
entryv
)
{
//
right
x
:=
M
.
entryv
[
ilo
]
right
:=
M
.
entryv
[
ilo
+
1
]
if
(
x
.
Hi_
+
1
==
right
.
Lo
)
&&
(
v
==
right
.
Value
)
{
vReplaceSlice
(&
M
.
entryv
,
ilo
,
ilo
+
2
,
RangedMapEntry
{
v
,
KeyRange
{
x
.
Lo
,
right
.
Hi_
}})
debugfRMap
(
"
\t
merge right
\t
-> %s
\n
"
,
M
)
if
ilo
+
1
<
len
(
S
.
rangev
)
{
//
right
if
S
.
rangev
[
ilo
].
Hi_
+
1
==
S
.
rangev
[
ilo
+
1
].
Lo
{
vReplaceSlice
(&
S
.
rangev
,
ilo
,
ilo
+
2
,
KeyRange
{
S
.
rangev
[
ilo
].
Lo
,
S
.
rangev
[
ilo
+
1
].
Hi_
})
debugfRSet
(
"
\t
merge right
\t
-> %s
\n
"
,
S
)
}
}
if
ilo
>
0
{
//
left
left
:=
M
.
entryv
[
ilo
-
1
]
x
:=
M
.
entryv
[
ilo
]
if
(
left
.
Hi_
+
1
==
x
.
Lo
)
&&
(
left
.
Value
==
v
)
{
vReplaceSlice
(&
M
.
entryv
,
ilo
-
1
,
ilo
+
1
,
RangedMapEntry
{
v
,
KeyRange
{
left
.
Lo
,
x
.
Hi_
}})
debugfRMap
(
"
\t
merge left
\t
-> %s
\n
"
,
M
)
if
S
.
rangev
[
ilo
-
1
].
Hi_
+
1
==
S
.
rangev
[
ilo
].
Lo
{
vReplaceSlice
(&
S
.
rangev
,
ilo
-
1
,
ilo
+
1
,
KeyRange
{
S
.
rangev
[
ilo
-
1
].
Lo
,
S
.
rangev
[
ilo
].
Hi_
})
debugfRSet
(
"
\t
merge left
\t
-> %s
\n
"
,
S
)
}
}
...
...
wcfs/internal/xbtree/blib/rangemap_test.go
View file @
24930939
...
...
@@ -130,9 +130,6 @@ func TestRangedMap(t *testing.T) {
M
(
1
,
2
,
a
,
2
,
6
,
x
,
6
,
8
,
b
),
// Set
M
(
1
,
2
,
a
,
6
,
8
,
b
),
// Del
n
),
// Has
}
for
_
,
tt
:=
range
testv
{
...
...
@@ -185,6 +182,7 @@ func verifyGet(t *testing.T, M *_RangedMap_str) {
var
Mranges
[]
RangedMapEntry
Mranges
=
append
(
Mranges
,
M
.
AllRanges
()
...
)
// copy just in case it changes on Get
// verify "has-data"
for
_
,
e
:=
range
Mranges
{
for
k
:=
e
.
Lo
;
k
<=
e
.
Hi_
;
k
++
{
v
,
ok
:=
M
.
Get_
(
k
)
...
...
@@ -195,7 +193,7 @@ func verifyGet(t *testing.T, M *_RangedMap_str) {
}
}
// verify
no-data
// verify
"no-data"
// NA = [-∞,∞) \ M
na
:=
RangedKeySet
{}
na
.
AddRange
(
KeyRange
{
-
10
,
+
10
})
// models -∞,∞
...
...
wcfs/internal/xbtree/blib/rangeset.go
View file @
24930939
...
...
@@ -150,7 +150,7 @@ func (S *RangedKeySet) AllRanges() /*readonly*/[]KeyRange {
return
rv
}
// XXX -> ptr?
func
(
S
RangedKeySet
)
String
()
string
{
return
S
.
m
.
String
()
// RangeMap<void> formats for set
// RangeMap<void> supports formatting for set out of the box
return
S
.
m
.
String
()
}
wcfs/internal/xbtree/blib/rangeset.go.orig
deleted
100644 → 0
View file @
ed2de0de
//
Copyright
(
C
)
2021
Nexedi
SA
and
Contributors
.
//
Kirill
Smelkov
<
kirr
@
nexedi
.
com
>
//
//
This
program
is
free
software
:
you
can
Use
,
Study
,
Modify
and
Redistribute
//
it
under
the
terms
of
the
GNU
General
Public
License
version
3
,
or
(
at
your
//
option
)
any
later
version
,
as
published
by
the
Free
Software
Foundation
.
//
//
You
can
also
Link
and
Combine
this
program
with
other
software
covered
by
//
the
terms
of
any
of
the
Free
Software
licenses
or
any
of
the
Open
Source
//
Initiative
approved
licenses
and
Convey
the
resulting
work
.
Corresponding
//
source
of
such
a
combination
shall
include
the
source
code
for
all
other
//
software
used
.
//
//
This
program
is
distributed
WITHOUT
ANY
WARRANTY
;
without
even
the
implied
//
warranty
of
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE
.
//
//
See
COPYING
file
for
full
licensing
terms
.
//
See
https
://
www
.
nexedi
.
com
/
licensing
for
rationale
and
options
.
package
blib
//
set
of
[
lo
,
hi
)
Key
ranges
.
import
(
"fmt"
"sort"
)
const
traceRangeSet
=
false
const
debugRangeSet
=
false
//
KeyRange
represents
[
lo
,
hi
)
Key
range
.
type
KeyRange
struct
{
Lo
Key
Hi_
Key
//
NOTE
_not_
hi
)
to
avoid
overflow
at
∞
;
hi
=
hi_
+
1
}
//
RangedKeySet
is
set
of
Keys
with
adjacent
keys
coalesced
into
Ranges
.
//
//
Zero
value
represents
empty
set
.
type
RangedKeySet
struct
{
//
TODO
rework
to
use
BTree
lo
->
hi_
instead
if
in
practice
in
treediff
,
//
and
other
usage
places
,
N
(
ranges
)
turns
out
to
be
not
small
//
(
i
.
e
.
performance
turns
out
to
be
not
acceptable
)
rangev
[]
KeyRange
//
lo
↑
}
//
Has
returns
whether
key
k
belongs
to
the
range
.
func
(
r
*
KeyRange
)
Has
(
k
Key
)
bool
{
return
(
r
.
Lo
<=
k
&&
k
<=
r
.
Hi_
)
}
//
Add
adds
key
k
to
the
set
.
func
(
S
*
RangedKeySet
)
Add
(
k
Key
)
{
S
.
AddRange
(
KeyRange
{
Lo
:
k
,
Hi_
:
k
})
}
//
Del
removes
key
k
from
the
set
.
func
(
S
*
RangedKeySet
)
Del
(
k
Key
)
{
S
.
DelRange
(
KeyRange
{
Lo
:
k
,
Hi_
:
k
})
}
//
Has
returns
whether
key
k
belongs
to
the
set
.
func
(
S
*
RangedKeySet
)
Has
(
k
Key
)
bool
{
return
S
.
HasRange
(
KeyRange
{
Lo
:
k
,
Hi_
:
k
})
}
//
AddRange
adds
range
r
to
the
set
.
func
(
S
*
RangedKeySet
)
AddRange
(
r
KeyRange
)
{
if
traceRangeSet
{
fmt
.
Printf
(
"
\n\n
AddRange:
\n
"
)
fmt
.
Printf
(
" S: %s
\n
"
,
S
)
fmt
.
Printf
(
" r: %s
\n
"
,
r
)
defer
fmt
.
Printf
(
"->u: %s
\n
"
,
S
)
}
S
.
verify
()
defer
S
.
verify
()
//
find
first
ilo
:
r
.
Lo
<
[
ilo
].
hi
l
:=
len
(
S
.
rangev
)
ilo
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
r
.
Lo
<=
S
.
rangev
[
i
].
Hi_
})
debugfRSet
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
//
not
found
S
.
rangev
=
append
(
S
.
rangev
,
r
)
l
++
debugfRSet
(
"
\t
append %s
\t
-> %s
\n
"
,
r
,
S
)
}
//
find
last
jhi
:
[
jhi
].
Lo
<
r
.
hi
jhi
:=
ilo
for
;;
jhi
++
{
if
jhi
==
l
{
break
}
if
S
.
rangev
[
jhi
].
Lo
<=
r
.
Hi_
{
continue
}
break
}
debugfRSet
(
"
\t
jhi: %d
\n
"
,
jhi
)
//
entries
in
[
ilo
:
jhi
)
∈
[
r
.
Lo
,
r
.
hi
)
and
should
be
merged
into
one
if
(
jhi
-
ilo
)
>
1
{
lo
:=
S
.
rangev
[
ilo
].
Lo
hi_
:=
S
.
rangev
[
jhi
-
1
].
Hi_
vReplaceSlice
(&
S
.
rangev
,
ilo
,
jhi
,
KeyRange
{
lo
,
hi_
})
debugfRSet
(
"
\t
merge S[%d:%d]
\t
-> %s
\n
"
,
ilo
,
jhi
,
S
)
}
jhi
=
-
1
//
no
longer
valid
//
if
[
r
.
lo
,
r
.
hi
)
was
outside
of
any
entry
-
create
new
entry
if
r
.
Hi_
<
S
.
rangev
[
ilo
].
Lo
{
vInsert
(&
S
.
rangev
,
ilo
,
r
)
debugfRSet
(
"
\t
insert %s
\t
-> %s
\n
"
,
r
,
S
)
}
//
now
we
have
covered
entries
merged
as
needed
into
[
ilo
]
//
extend
this
entry
if
r
coverage
is
wider
if
r
.
Lo
<
S
.
rangev
[
ilo
].
Lo
{
S
.
rangev
[
ilo
].
Lo
=
r
.
Lo
debugfRSet
(
"
\t
extend left
\t
-> %s
\n
"
,
S
)
}
if
r
.
Hi_
>
S
.
rangev
[
ilo
].
Hi_
{
S
.
rangev
[
ilo
].
Hi_
=
r
.
Hi_
debugfRSet
(
"
\t
extend right
\t
-> %s
\n
"
,
S
)
}
//
and
check
if
we
should
merge
it
with
right
/
left
neighbours
if
ilo
+
1
<
len
(
S
.
rangev
)
{
//
right
if
S
.
rangev
[
ilo
].
Hi_
+
1
==
S
.
rangev
[
ilo
+
1
].
Lo
{
vReplaceSlice
(&
S
.
rangev
,
ilo
,
ilo
+
2
,
KeyRange
{
S
.
rangev
[
ilo
].
Lo
,
S
.
rangev
[
ilo
+
1
].
Hi_
})
debugfRSet
(
"
\t
merge right
\t
-> %s
\n
"
,
S
)
}
}
if
ilo
>
0
{
//
left
if
S
.
rangev
[
ilo
-
1
].
Hi_
+
1
==
S
.
rangev
[
ilo
].
Lo
{
vReplaceSlice
(&
S
.
rangev
,
ilo
-
1
,
ilo
+
1
,
KeyRange
{
S
.
rangev
[
ilo
-
1
].
Lo
,
S
.
rangev
[
ilo
].
Hi_
})
debugfRSet
(
"
\t
merge left
\t
-> %s
\n
"
,
S
)
}
}
//
done
}
//
DelRange
removes
range
r
from
the
set
.
func
(
S
*
RangedKeySet
)
DelRange
(
r
KeyRange
)
{
if
traceRangeSet
{
fmt
.
Printf
(
"
\n\n
DelRange:
\n
"
)
fmt
.
Printf
(
" S: %s
\n
"
,
S
)
fmt
.
Printf
(
" r: %s
\n
"
,
r
)
defer
fmt
.
Printf
(
"->d: %s
\n
"
,
S
)
}
S
.
verify
()
defer
S
.
verify
()
//
find
first
ilo
:
r
.
Lo
<
[
ilo
].
hi
l
:=
len
(
S
.
rangev
)
ilo
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
r
.
Lo
<=
S
.
rangev
[
i
].
Hi_
})
debugfRSet
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
//
not
found
debugfRSet
(
"
\t
non-overlap right
\n
"
)
return
}
//
find
last
jhi
:
[
jhi
].
Lo
<
r
.
hi
jhi
:=
ilo
for
;;
jhi
++
{
if
jhi
==
l
{
break
}
if
S
.
rangev
[
jhi
].
Lo
<=
r
.
Hi_
{
continue
}
break
}
debugfRSet
(
"
\t
jhi: %d
\n
"
,
jhi
)
if
jhi
==
0
{
debugfRSet
(
"
\t
non-overlap left
\n
"
)
return
}
//
[
ilo
+
1
:
jhi
-
1
]
should
be
deleted
//
[
ilo
]
and
[
jhi
-
1
]
overlap
with
[
r
.
lo
,
r
.
hi
)
-
they
should
be
deleted
,
or
shrinked
,
//
or
split
+
shrinked
if
ilo
==
jhi
-
1
and
r
is
inside
[
ilo
]
if
jhi
-
ilo
==
1
&&
S
.
rangev
[
ilo
].
Lo
<
r
.
Lo
&&
r
.
Hi_
<
S
.
rangev
[
ilo
].
Hi_
{
x
:=
S
.
rangev
[
ilo
]
vInsert
(&
S
.
rangev
,
ilo
,
x
)
jhi
++
debugfRSet
(
"
\t
presplit copy %s
\t
-> %s
\n
"
,
x
,
S
)
}
if
S
.
rangev
[
ilo
].
Lo
<
r
.
Lo
{
//
shrink
left
S
.
rangev
[
ilo
]
=
KeyRange
{
S
.
rangev
[
ilo
].
Lo
,
r
.
Lo
-
1
}
ilo
++
debugfRSet
(
"
\t
shrink [%d] left
\t
-> %s
\n
"
,
ilo
,
S
)
}
if
r
.
Hi_
<
S
.
rangev
[
jhi
-
1
].
Hi_
{
//
shrink
right
S
.
rangev
[
jhi
-
1
]
=
KeyRange
{
r
.
Hi_
+
1
,
S
.
rangev
[
jhi
-
1
].
Hi_
}
jhi
--
debugfRSet
(
"
\t
shrink [%d] right
\t
-> %s
\n
"
,
jhi
-
1
,
S
)
}
if
(
jhi
-
ilo
)
>
0
{
vDeleteSlice
(&
S
.
rangev
,
ilo
,
jhi
)
debugfRSet
(
"
\t
delete S[%d:%d]
\t
-> %s
\n
"
,
ilo
,
jhi
,
S
)
}
//
done
}
//
HasRange
returns
whether
all
keys
from
range
r
belong
to
the
set
.
func
(
S
*
RangedKeySet
)
HasRange
(
r
KeyRange
)
(
yes
bool
)
{
if
traceRangeSet
{
fmt
.
Printf
(
"
\n\n
HasRange:
\n
"
)
fmt
.
Printf
(
" S: %s
\n
"
,
S
)
fmt
.
Printf
(
" r: %s
\n
"
,
r
)
defer
func
()
{
fmt
.
Printf
(
"->·: %v
\n
"
,
yes
)
}()
}
S
.
verify
()
//
find
first
ilo
:
r
.
lo
<
[
ilo
].
hi
l
:=
len
(
S
.
rangev
)
ilo
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
r
.
Lo
<=
S
.
rangev
[
i
].
Hi_
})
debugfRSet
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
//
not
found
return
false
}
//
all
keys
from
r
are
in
S
if
r
∈
[
ilo
]
return
(
S
.
rangev
[
ilo
].
Lo
<=
r
.
Lo
&&
r
.
Hi_
<=
S
.
rangev
[
ilo
].
Hi_
)
}
//
Union
returns
RangedKeySet
(
A
.
keys
|
B
.
keys
).
func
(
A
*
RangedKeySet
)
Union
(
B
*
RangedKeySet
)
*
RangedKeySet
{
U
:=
A
.
Clone
()
U
.
UnionInplace
(
B
)
return
U
}
//
Difference
returns
RangedKeySet
(
A
.
keys
\
B
.
keys
).
func
(
A
*
RangedKeySet
)
Difference
(
B
*
RangedKeySet
)
*
RangedKeySet
{
D
:=
A
.
Clone
()
D
.
DifferenceInplace
(
B
)
return
D
}
//
XXX
Intersection
func
(
A
*
RangedKeySet
)
UnionInplace
(
B
*
RangedKeySet
)
{
A
.
verify
()
B
.
verify
()
defer
A
.
verify
()
//
XXX
dumb
for
_
,
r
:=
range
B
.
rangev
{
A
.
AddRange
(
r
)
}
}
func
(
A
*
RangedKeySet
)
DifferenceInplace
(
B
*
RangedKeySet
)
{
A
.
verify
()
B
.
verify
()
defer
A
.
verify
()
//
XXX
dumb
for
_
,
r
:=
range
B
.
rangev
{
if
len
(
A
.
rangev
)
==
0
{
break
}
A
.
DelRange
(
r
)
}
}
//
--------
//
verify
checks
RangedKeySet
for
internal
consistency
:
//
-
ranges
must
be
not
overlapping
nor
adjacent
and
↑
func
(
S
*
RangedKeySet
)
verify
()
{
//
TODO
!debug -> return
var
badv
[]
string
badf
:=
func
(
format
string
,
argv
...
interface
{})
{
badv
=
append
(
badv
,
fmt
.
Sprintf
(
format
,
argv
...))
}
defer
func
()
{
if
badv
!= nil {
emsg
:=
"S.verify: fail:
\n\n
"
for
_
,
bad
:=
range
badv
{
emsg
+=
fmt
.
Sprintf
(
"- %s
\n
"
,
bad
)
}
emsg
+=
fmt
.
Sprintf
(
"
\n
S: %s
\n
"
,
S
)
panic
(
emsg
)
}
}()
hi_Prev
:=
KeyMin
for
i
,
r
:=
range
S
.
rangev
{
hiPrev
:=
hi_Prev
+
1
if
i
>
0
&&
!(hiPrev < r.Lo) { // NOTE not ≤ - adjacent ranges must be merged
badf
(
"[%d]: !(hiPrev < r.lo)"
,
i
)
}
if
!(r.Lo <= r.Hi_) {
badf
(
"[%d]: !(r.lo <= r.hi_)"
,
i
)
}
hi_Prev
=
r
.
Hi_
}
}
//
Clone
returns
copy
of
the
set
.
func
(
orig
*
RangedKeySet
)
Clone
()
*
RangedKeySet
{
klon
:=
&
RangedKeySet
{}
klon
.
rangev
=
append
(
klon
.
rangev
,
orig
.
rangev
...)
return
klon
}
//
Empty
returns
whether
the
set
is
empty
.
func
(
S
*
RangedKeySet
)
Empty
()
bool
{
return
len
(
S
.
rangev
)
==
0
}
//
Equal
returns
whether
A
==
B
.
func
(
A
*
RangedKeySet
)
Equal
(
B
*
RangedKeySet
)
bool
{
if
len
(
A
.
rangev
)
!= len(B.rangev) {
return
false
}
for
i
,
ra
:=
range
A
.
rangev
{
rb
:=
B
.
rangev
[
i
]
if
ra
!= rb {
return
false
}
}
return
true
}
//
Clear
removes
all
elements
from
the
set
.
func
(
S
*
RangedKeySet
)
Clear
()
{
S
.
rangev
=
nil
}
//
AllRanges
returns
slice
of
all
key
ranges
in
the
set
.
//
//
TODO
->
iter
?
func
(
S
*
RangedKeySet
)
AllRanges
()
/*
readonly
*/[]
KeyRange
{
return
S
.
rangev
}
//
XXX
->
ptr
?
func
(
S
RangedKeySet
)
String
()
string
{
s
:=
"{"
for
i
,
r
:=
range
S
.
rangev
{
if
i
>
0
{
s
+=
" "
}
s
+=
r
.
String
()
}
s
+=
"}"
return
s
}
func
(
r
KeyRange
)
String
()
string
{
var
shi
string
if
r
.
Hi_
==
KeyMax
{
shi
=
KStr
(
r
.
Hi_
)
//
∞
}
else
{
shi
=
fmt
.
Sprintf
(
"%d"
,
r
.
Hi_
+
1
)
}
return
fmt
.
Sprintf
(
"[%s,%s)"
,
KStr
(
r
.
Lo
),
shi
)
}
func
debugfRSet
(
format
string
,
argv
...
interface
{})
{
if
!debugRangeSet {
return
}
fmt
.
Printf
(
format
,
argv
...)
}
//
----
slice
ops
----
//
vInsert
inserts
r
into
*
pv
[
i
].
func
vInsert
(
pv
*[]
KeyRange
,
i
int
,
r
KeyRange
)
{
v
:=
*
pv
v
=
append
(
v
,
KeyRange
{})
copy
(
v
[
i
+
1
:],
v
[
i
:])
v
[
i
]
=
r
*
pv
=
v
}
//
vDeleteSlice
deletes
*
pv
[
lo
:
hi
].
func
vDeleteSlice
(
pv
*[]
KeyRange
,
lo
,
hi
int
)
{
v
:=
*
pv
n
:=
copy
(
v
[
lo
:],
v
[
hi
:])
v
=
v
[:
lo
+
n
]
*
pv
=
v
}
//
vReplaceSlice
replaces
*
pv
[
lo
:
hi
]
with
r
.
func
vReplaceSlice
(
pv
*[]
KeyRange
,
lo
,
hi
int
,
r
KeyRange
)
{
v
:=
*
pv
n
:=
copy
(
v
[
lo
+
1
:],
v
[
hi
:])
v
[
lo
]
=
r
v
=
v
[:
lo
+
1
+
n
]
*
pv
=
v
}
wcfs/internal/xbtree/blib/zrangemap_str.go
View file @
24930939
...
...
@@ -27,8 +27,8 @@ import (
"sort"
)
const
trace_RangedMap_str
=
tru
e
const
debug_RangedMap_str
=
tru
e
const
trace_RangedMap_str
=
fals
e
const
debug_RangedMap_str
=
fals
e
// _RangedMap_str is Key->string map with adjacent keys mapped to the same value coalesced into Ranges.
//
...
...
@@ -118,7 +118,8 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
defer
M
.
verify
()
// clear range for r and insert new entry
// TODO optimize for set case (just merge all covered entries into one)
// TODO optimize for set case (just merge all covered entries into one -
// - see commented AddRange vvv)
i
:=
M
.
delRange
(
r
)
vInsert__RangedMap_str
(
&
M
.
entryv
,
i
,
e
)
debugf_RangedMap_str
(
"
\t
insert %s
\t
-> %s
\n
"
,
e
,
M
)
...
...
@@ -146,18 +147,18 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
// done
/*
/*
how it was for just set:
// find first ilo: r.Lo < [ilo].hi
l := len(
M.entry
v)
l := len(
S.range
v)
ilo := sort.Search(l, func(i int) bool {
return r.Lo <=
M.entry
v[i].Hi_
return r.Lo <=
S.range
v[i].Hi_
})
debugf
_RangedMap_str
("\tilo: %d\n", ilo)
debugf
RSet
("\tilo: %d\n", ilo)
if ilo == l { // not found
M.entryv = append(M.entryv, e
)
S.rangev = append(S.rangev, r
)
l++
debugf
_RangedMap_str("\tappend %s\t-> %s\n", e, M
)
debugf
RSet("\tappend %s\t-> %s\n", r, S
)
}
// find last jhi: [jhi].Lo < r.hi
...
...
@@ -166,97 +167,53 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
if jhi == l {
break
}
if
M.entry
v[jhi].Lo <= r.Hi_ {
if
S.range
v[jhi].Lo <= r.Hi_ {
continue
}
break
}
debugf_RangedMap_str("\tjhi: %d\n", jhi)
// [ilo+1:jhi-1] should be deleted
if (jhi - ilo) > 2 {
vDeleteSlice__RangedMap_str(&M.entryv, ilo+1,jhi-1)
debugf_RangedMap_str("\tdelete M[%d:%d]\t-> %s\n", ilo+1, jhi-1, M)
}
// if r was overlapping with sole region -> presplit it TODO only if !vsame
x := M.entryv[ilo]
if jhi-ilo == 1 && x.Lo < r.Lo && r.Hi_ < x.Hi_ {
vInsert__RangedMap_str(&M.entryv, ilo, x)
jhi++
debugf_RangedMap_str("\tpresplit copy %s\t-> %s\n", x, M)
}
jhi = -1 // no longer valid
// create new entry
// now it is
vInsert__RangedMap_str(&M.entryv, ilo+1, e)
// [ilo] is now to the left
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - XXX
if jhi-ilo == 1 {
x := M.entryv[ilo]
if x.Value != v {
vInsert__RangedMap_str(&M.entryv, ilo, x)
jhi++
debugf_RangedMap_str("\tpresplit copy %s\t-> %s\n", x, M)
} else {
// XXX extend left/right if needed XXX here?
}
}
if xl.Value != v {
}
debugfRSet("\tjhi: %d\n", jhi)
// entries in [ilo:jhi) ∈ [r.Lo,r.hi) and should be merged into one
// FIXME check different values
if (jhi - ilo) > 1 {
lo :=
M.entry
v[ilo].Lo
hi_ :=
M.entry
v[jhi-1].Hi_
vReplaceSlice__RangedMap_str(&
M.entryv, ilo,jhi, _RangedMap_strEntry{v, KeyRange{lo,hi_}
})
debugf
_RangedMap_str("\tmerge M[%d:%d]\t-> %s\n", ilo, jhi, M
)
lo :=
S.range
v[ilo].Lo
hi_ :=
S.range
v[jhi-1].Hi_
vReplaceSlice__RangedMap_str(&
S.rangev, ilo,jhi, KeyRange{lo,hi_
})
debugf
RSet("\tmerge S[%d:%d]\t-> %s\n", ilo, jhi, S
)
}
jhi = -1 // no longer valid
// if [r.lo,r.hi) was outside of any entry - create new entry
if r.Hi_ <
M.entry
v[ilo].Lo {
vInsert__RangedMap_str(&
M.entryv, ilo, e
)
debugf
_RangedMap_str("\tinsert %s\t-> %s\n", e, M
)
if r.Hi_ <
S.range
v[ilo].Lo {
vInsert__RangedMap_str(&
S.rangev, ilo, r
)
debugf
RSet("\tinsert %s\t-> %s\n", r, S
)
}
// now we have covered entries merged as needed into [ilo]
// extend this entry if r coverage is wider
if r.Lo <
M.entry
v[ilo].Lo {
M.entry
v[ilo].Lo = r.Lo
debugf
_RangedMap_str("\textend left\t-> %s\n", M
)
if r.Lo <
S.range
v[ilo].Lo {
S.range
v[ilo].Lo = r.Lo
debugf
RSet("\textend left\t-> %s\n", S
)
}
if r.Hi_ >
M.entry
v[ilo].Hi_ {
M.entry
v[ilo].Hi_ = r.Hi_
debugf
_RangedMap_str("\textend right\t-> %s\n", M
)
if r.Hi_ >
S.range
v[ilo].Hi_ {
S.range
v[ilo].Hi_ = r.Hi_
debugf
RSet("\textend right\t-> %s\n", S
)
}
// and check if we should merge it with right/left neighbours
if ilo+1 < len(M.entryv) { // right
x := M.entryv[ilo]
right := M.entryv[ilo+1]
if (x.Hi_+1 == right.Lo) && (v == right.Value) {
vReplaceSlice__RangedMap_str(&M.entryv, ilo,ilo+2,
_RangedMap_strEntry{v, KeyRange{x.Lo, right.Hi_}})
debugf_RangedMap_str("\tmerge right\t-> %s\n", M)
if ilo+1 < len(S.rangev) { // right
if S.rangev[ilo].Hi_+1 == S.rangev[ilo+1].Lo {
vReplaceSlice__RangedMap_str(&S.rangev, ilo,ilo+2,
KeyRange{S.rangev[ilo].Lo, S.rangev[ilo+1].Hi_})
debugfRSet("\tmerge right\t-> %s\n", S)
}
}
if ilo > 0 { // left
left := M.entryv[ilo-1]
x := M.entryv[ilo]
if (left.Hi_+1 == x.Lo) && (left.Value == v) {
vReplaceSlice__RangedMap_str(&M.entryv, ilo-1,ilo+1,
_RangedMap_strEntry{v, KeyRange{left.Lo, x.Hi_}})
debugf_RangedMap_str("\tmerge left\t-> %s\n", M)
if S.rangev[ilo-1].Hi_+1 == S.rangev[ilo].Lo {
vReplaceSlice__RangedMap_str(&S.rangev, ilo-1,ilo+1,
KeyRange{S.rangev[ilo-1].Lo, S.rangev[ilo].Hi_})
debugfRSet("\tmerge left\t-> %s\n", S)
}
}
...
...
wcfs/internal/xbtree/blib/zrangemap_void.go
View file @
24930939
...
...
@@ -27,8 +27,8 @@ import (
"sort"
)
const
trace_RangedMap_void
=
tru
e
const
debug_RangedMap_void
=
tru
e
const
trace_RangedMap_void
=
fals
e
const
debug_RangedMap_void
=
fals
e
// _RangedMap_void is Key->void map with adjacent keys mapped to the same value coalesced into Ranges.
//
...
...
@@ -118,7 +118,8 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
defer
M
.
verify
()
// clear range for r and insert new entry
// TODO optimize for set case (just merge all covered entries into one)
// TODO optimize for set case (just merge all covered entries into one -
// - see commented AddRange vvv)
i
:=
M
.
delRange
(
r
)
vInsert__RangedMap_void
(
&
M
.
entryv
,
i
,
e
)
debugf_RangedMap_void
(
"
\t
insert %s
\t
-> %s
\n
"
,
e
,
M
)
...
...
@@ -146,18 +147,18 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
// done
/*
/*
how it was for just set:
// find first ilo: r.Lo < [ilo].hi
l := len(
M.entry
v)
l := len(
S.range
v)
ilo := sort.Search(l, func(i int) bool {
return r.Lo <=
M.entry
v[i].Hi_
return r.Lo <=
S.range
v[i].Hi_
})
debugf
_RangedMap_void
("\tilo: %d\n", ilo)
debugf
RSet
("\tilo: %d\n", ilo)
if ilo == l { // not found
M.entryv = append(M.entryv, e
)
S.rangev = append(S.rangev, r
)
l++
debugf
_RangedMap_void("\tappend %s\t-> %s\n", e, M
)
debugf
RSet("\tappend %s\t-> %s\n", r, S
)
}
// find last jhi: [jhi].Lo < r.hi
...
...
@@ -166,97 +167,53 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
if jhi == l {
break
}
if
M.entry
v[jhi].Lo <= r.Hi_ {
if
S.range
v[jhi].Lo <= r.Hi_ {
continue
}
break
}
debugf_RangedMap_void("\tjhi: %d\n", jhi)
// [ilo+1:jhi-1] should be deleted
if (jhi - ilo) > 2 {
vDeleteSlice__RangedMap_void(&M.entryv, ilo+1,jhi-1)
debugf_RangedMap_void("\tdelete M[%d:%d]\t-> %s\n", ilo+1, jhi-1, M)
}
// if r was overlapping with sole region -> presplit it TODO only if !vsame
x := M.entryv[ilo]
if jhi-ilo == 1 && x.Lo < r.Lo && r.Hi_ < x.Hi_ {
vInsert__RangedMap_void(&M.entryv, ilo, x)
jhi++
debugf_RangedMap_void("\tpresplit copy %s\t-> %s\n", x, M)
}
jhi = -1 // no longer valid
// create new entry
// now it is
vInsert__RangedMap_void(&M.entryv, ilo+1, e)
// [ilo] is now to the left
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - XXX
if jhi-ilo == 1 {
x := M.entryv[ilo]
if x.Value != v {
vInsert__RangedMap_void(&M.entryv, ilo, x)
jhi++
debugf_RangedMap_void("\tpresplit copy %s\t-> %s\n", x, M)
} else {
// XXX extend left/right if needed XXX here?
}
}
if xl.Value != v {
}
debugfRSet("\tjhi: %d\n", jhi)
// entries in [ilo:jhi) ∈ [r.Lo,r.hi) and should be merged into one
// FIXME check different values
if (jhi - ilo) > 1 {
lo :=
M.entry
v[ilo].Lo
hi_ :=
M.entry
v[jhi-1].Hi_
vReplaceSlice__RangedMap_void(&
M.entryv, ilo,jhi, _RangedMap_voidEntry{v, KeyRange{lo,hi_}
})
debugf
_RangedMap_void("\tmerge M[%d:%d]\t-> %s\n", ilo, jhi, M
)
lo :=
S.range
v[ilo].Lo
hi_ :=
S.range
v[jhi-1].Hi_
vReplaceSlice__RangedMap_void(&
S.rangev, ilo,jhi, KeyRange{lo,hi_
})
debugf
RSet("\tmerge S[%d:%d]\t-> %s\n", ilo, jhi, S
)
}
jhi = -1 // no longer valid
// if [r.lo,r.hi) was outside of any entry - create new entry
if r.Hi_ <
M.entry
v[ilo].Lo {
vInsert__RangedMap_void(&
M.entryv, ilo, e
)
debugf
_RangedMap_void("\tinsert %s\t-> %s\n", e, M
)
if r.Hi_ <
S.range
v[ilo].Lo {
vInsert__RangedMap_void(&
S.rangev, ilo, r
)
debugf
RSet("\tinsert %s\t-> %s\n", r, S
)
}
// now we have covered entries merged as needed into [ilo]
// extend this entry if r coverage is wider
if r.Lo <
M.entry
v[ilo].Lo {
M.entry
v[ilo].Lo = r.Lo
debugf
_RangedMap_void("\textend left\t-> %s\n", M
)
if r.Lo <
S.range
v[ilo].Lo {
S.range
v[ilo].Lo = r.Lo
debugf
RSet("\textend left\t-> %s\n", S
)
}
if r.Hi_ >
M.entry
v[ilo].Hi_ {
M.entry
v[ilo].Hi_ = r.Hi_
debugf
_RangedMap_void("\textend right\t-> %s\n", M
)
if r.Hi_ >
S.range
v[ilo].Hi_ {
S.range
v[ilo].Hi_ = r.Hi_
debugf
RSet("\textend right\t-> %s\n", S
)
}
// and check if we should merge it with right/left neighbours
if ilo+1 < len(M.entryv) { // right
x := M.entryv[ilo]
right := M.entryv[ilo+1]
if (x.Hi_+1 == right.Lo) && (v == right.Value) {
vReplaceSlice__RangedMap_void(&M.entryv, ilo,ilo+2,
_RangedMap_voidEntry{v, KeyRange{x.Lo, right.Hi_}})
debugf_RangedMap_void("\tmerge right\t-> %s\n", M)
if ilo+1 < len(S.rangev) { // right
if S.rangev[ilo].Hi_+1 == S.rangev[ilo+1].Lo {
vReplaceSlice__RangedMap_void(&S.rangev, ilo,ilo+2,
KeyRange{S.rangev[ilo].Lo, S.rangev[ilo+1].Hi_})
debugfRSet("\tmerge right\t-> %s\n", S)
}
}
if ilo > 0 { // left
left := M.entryv[ilo-1]
x := M.entryv[ilo]
if (left.Hi_+1 == x.Lo) && (left.Value == v) {
vReplaceSlice__RangedMap_void(&M.entryv, ilo-1,ilo+1,
_RangedMap_voidEntry{v, KeyRange{left.Lo, x.Hi_}})
debugf_RangedMap_void("\tmerge left\t-> %s\n", M)
if S.rangev[ilo-1].Hi_+1 == S.rangev[ilo].Lo {
vReplaceSlice__RangedMap_void(&S.rangev, ilo-1,ilo+1,
KeyRange{S.rangev[ilo-1].Lo, S.rangev[ilo].Hi_})
debugfRSet("\tmerge left\t-> %s\n", S)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment