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
0aff75b0
Commit
0aff75b0
authored
Sep 27, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
87f373f5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
470 additions
and
4 deletions
+470
-4
wcfs/internal/xbtree/blib/rangemap.go.in
wcfs/internal/xbtree/blib/rangemap.go.in
+2
-2
wcfs/internal/xbtree/blib/rangemap_test.go
wcfs/internal/xbtree/blib/rangemap_test.go
+30
-0
wcfs/internal/xbtree/blib/zrangemap_str.go
wcfs/internal/xbtree/blib/zrangemap_str.go
+436
-0
wcfs/internal/xbtree/blib/zrangemap_void.go
wcfs/internal/xbtree/blib/zrangemap_void.go
+2
-2
No files found.
wcfs/internal/xbtree/blib/rangemap.go.in
View file @
0aff75b0
...
@@ -153,8 +153,8 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
...
@@ -153,8 +153,8 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
//
if
[
r
.
lo
,
r
.
hi
)
was
outside
of
any
entry
-
create
new
entry
//
if
[
r
.
lo
,
r
.
hi
)
was
outside
of
any
entry
-
create
new
entry
if
r
.
Hi_
<
M
.
entryv
[
ilo
].
Lo
{
if
r
.
Hi_
<
M
.
entryv
[
ilo
].
Lo
{
vInsert
(&
M
.
entryv
,
ilo
,
r
)
vInsert
(&
M
.
entryv
,
ilo
,
e
)
debugfRMap
(
"
\t
insert %s
\t
-> %s
\n
"
,
r
,
M
)
debugfRMap
(
"
\t
insert %s
\t
-> %s
\n
"
,
e
,
M
)
}
}
//
now
we
have
covered
entries
merged
as
needed
into
[
ilo
]
//
now
we
have
covered
entries
merged
as
needed
into
[
ilo
]
...
...
wcfs/internal/xbtree/blib/rangemap_test.go
0 → 100644
View file @
0aff75b0
// 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
//go:generate ./gen-rangemap _RangedMap_str string zrangemap_str.go
import
(
"testing"
)
func
TestRangeMap
(
t
*
testing
.
T
)
{
// XXX
}
wcfs/internal/xbtree/blib/zrangemap_str.go
0 → 100644
View file @
0aff75b0
// Code generated by gen-rangemap _RangedMap_str string; DO NOT EDIT.
// 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
// map [lo,hi) Key ranges to values.
import
(
"fmt"
"sort"
)
const
trace_RangedMap_str
=
true
const
debug_RangedMap_str
=
true
// _RangedMap_str is Key->string map with adjacent keys mapped to the same value coalesced into Ranges.
//
// Zero value represents empty map.
type
_RangedMap_str
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)
entryv
[]
_RangedMap_strEntry
// lo↑
}
// _RangedMap_strEntry represents one entry in _RangedMap_str.
type
_RangedMap_strEntry
struct
{
KeyRange
Value
string
}
// Get returns value associated with key k.
func
(
M
*
_RangedMap_str
)
Get
(
k
Key
)
string
{
v
,
_
:=
M
.
Get_
(
k
)
return
v
}
// Set changes M to map key k to value v.
func
(
M
*
_RangedMap_str
)
Set
(
k
Key
,
v
string
)
{
M
.
SetRange
(
KeyRange
{
Lo
:
k
,
Hi_
:
k
},
v
)
}
// Del removes key k.
func
(
M
*
_RangedMap_str
)
Del
(
k
Key
)
{
M
.
DelRange
(
KeyRange
{
Lo
:
k
,
Hi_
:
k
})
}
// Has returns whether key k is present in the map.
func
(
M
*
_RangedMap_str
)
Has
(
k
Key
)
bool
{
_
,
ok
:=
M
.
Get_
(
k
)
return
ok
}
// Get_ is comma-ok version of Get.
func
(
M
*
_RangedMap_str
)
Get_
(
k
Key
)
(
v
string
,
ok
bool
)
{
if
trace_RangedMap_str
{
fmt
.
Printf
(
"
\n\n
Get_:
\n
"
)
fmt
.
Printf
(
" M: %s
\n
"
,
M
)
fmt
.
Printf
(
" k: %s
\n
"
,
k
)
defer
func
()
{
fmt
.
Printf
(
"->·: %v, %t
\n
"
,
v
,
ok
)
}()
}
M
.
verify
()
// find first ilo: k < [ilo].hi
l
:=
len
(
M
.
entryv
)
ilo
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
k
<=
M
.
entryv
[
i
]
.
Hi_
})
debugf_RangedMap_str
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
// not found
return
}
e
:=
M
.
entryv
[
ilo
]
if
!
(
e
.
Lo
<=
k
)
{
// not found
return
}
// found
return
e
.
Value
,
true
}
// SetRange changes M to map key range r to value v.
func
(
M
*
_RangedMap_str
)
SetRange
(
r
KeyRange
,
v
string
)
{
e
:=
_RangedMap_strEntry
{
r
,
v
}
if
trace_RangedMap_str
{
fmt
.
Printf
(
"
\n\n
SetRange:
\n
"
)
fmt
.
Printf
(
" M: %s
\n
"
,
M
)
fmt
.
Printf
(
" e: %s
\n
"
,
e
)
defer
fmt
.
Printf
(
"->u: %s
\n
"
,
M
)
}
M
.
verify
()
defer
M
.
verify
()
// find first ilo: r.Lo < [ilo].hi
l
:=
len
(
M
.
entryv
)
ilo
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
r
.
Lo
<=
M
.
entryv
[
i
]
.
Hi_
})
debugf_RangedMap_str
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
// not found
M
.
entryv
=
append
(
M
.
entryv
,
e
)
l
++
debugf_RangedMap_str
(
"
\t
append %s
\t
-> %s
\n
"
,
e
,
M
)
}
// find last jhi: [jhi].Lo < r.hi
jhi
:=
ilo
for
;;
jhi
++
{
if
jhi
==
l
{
break
}
if
M
.
entryv
[
jhi
]
.
Lo
<=
r
.
Hi_
{
continue
}
break
}
debugf_RangedMap_str
(
"
\t
jhi: %d
\n
"
,
jhi
)
// entries in [ilo:jhi) ∈ [r.Lo,r.hi) and should be merged into one
// XXX check different values
if
(
jhi
-
ilo
)
>
1
{
lo
:=
M
.
entryv
[
ilo
]
.
Lo
hi_
:=
M
.
entryv
[
jhi
-
1
]
.
Hi_
vReplaceSlice__RangedMap_str
(
&
M
.
entryv
,
ilo
,
jhi
,
KeyRange
{
lo
,
hi_
})
debugf_RangedMap_str
(
"
\t
merge M[%d:%d]
\t
-> %s
\n
"
,
ilo
,
jhi
,
M
)
}
jhi
=
-
1
// no longer valid
// if [r.lo,r.hi) was outside of any entry - create new entry
if
r
.
Hi_
<
M
.
entryv
[
ilo
]
.
Lo
{
vInsert__RangedMap_str
(
&
M
.
entryv
,
ilo
,
e
)
debugf_RangedMap_str
(
"
\t
insert %s
\t
-> %s
\n
"
,
e
,
M
)
}
// now we have covered entries merged as needed into [ilo]
// extend this entry if r coverage is wider
if
r
.
Lo
<
M
.
entryv
[
ilo
]
.
Lo
{
M
.
entryv
[
ilo
]
.
Lo
=
r
.
Lo
debugf_RangedMap_str
(
"
\t
extend left
\t
-> %s
\n
"
,
M
)
}
if
r
.
Hi_
>
M
.
entryv
[
ilo
]
.
Hi_
{
M
.
entryv
[
ilo
]
.
Hi_
=
r
.
Hi_
debugf_RangedMap_str
(
"
\t
extend right
\t
-> %s
\n
"
,
M
)
}
// and check if we should merge it with right/left neighbours
if
ilo
+
1
<
len
(
M
.
entryv
)
{
// right
if
M
.
entryv
[
ilo
]
.
Hi_
+
1
==
M
.
entryv
[
ilo
+
1
]
.
Lo
{
// XXX && .Value same
vReplaceSlice__RangedMap_str
(
&
M
.
entryv
,
ilo
,
ilo
+
2
,
KeyRange
{
M
.
entryv
[
ilo
]
.
Lo
,
M
.
entryv
[
ilo
+
1
]
.
Hi_
})
debugf_RangedMap_str
(
"
\t
merge right
\t
-> %s
\n
"
,
M
)
}
}
if
ilo
>
0
{
// left
if
M
.
entryv
[
ilo
-
1
]
.
Hi_
+
1
==
M
.
entryv
[
ilo
]
.
Lo
{
// XXX && .Value same
vReplaceSlice__RangedMap_str
(
&
M
.
entryv
,
ilo
-
1
,
ilo
+
1
,
KeyRange
{
M
.
entryv
[
ilo
-
1
]
.
Lo
,
M
.
entryv
[
ilo
]
.
Hi_
})
debugf_RangedMap_str
(
"
\t
merge left
\t
-> %s
\n
"
,
M
)
}
}
// done
}
// DelRange removes range r from the map.
func
(
M
*
_RangedMap_str
)
DelRange
(
r
KeyRange
)
{
if
trace_RangedMap_str
{
fmt
.
Printf
(
"
\n\n
DelRange:
\n
"
)
fmt
.
Printf
(
" M: %s
\n
"
,
M
)
fmt
.
Printf
(
" r: %s
\n
"
,
r
)
defer
fmt
.
Printf
(
"->d: %s
\n
"
,
M
)
}
M
.
verify
()
defer
M
.
verify
()
// find first ilo: r.Lo < [ilo].hi
l
:=
len
(
M
.
entryv
)
ilo
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
r
.
Lo
<=
M
.
entryv
[
i
]
.
Hi_
})
debugf_RangedMap_str
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
// not found
debugf_RangedMap_str
(
"
\t
non-overlap right
\n
"
)
return
}
// find last jhi: [jhi].Lo < r.hi
jhi
:=
ilo
for
;;
jhi
++
{
if
jhi
==
l
{
break
}
if
M
.
entryv
[
jhi
]
.
Lo
<=
r
.
Hi_
{
continue
}
break
}
debugf_RangedMap_str
(
"
\t
jhi: %d
\n
"
,
jhi
)
if
jhi
==
0
{
debugf_RangedMap_str
(
"
\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
&&
M
.
entryv
[
ilo
]
.
Lo
<
r
.
Lo
&&
r
.
Hi_
<
M
.
entryv
[
ilo
]
.
Hi_
{
x
:=
M
.
entryv
[
ilo
]
vInsert__RangedMap_str
(
&
M
.
entryv
,
ilo
,
x
)
jhi
++
debugf_RangedMap_str
(
"
\t
presplit copy %s
\t
-> %s
\n
"
,
x
,
M
)
}
if
M
.
entryv
[
ilo
]
.
Lo
<
r
.
Lo
{
// shrink left
M
.
entryv
[
ilo
]
.
Hi_
=
r
.
Lo
-
1
ilo
++
debugf_RangedMap_str
(
"
\t
shrink [%d] left
\t
-> %s
\n
"
,
ilo
,
M
)
}
if
r
.
Hi_
<
M
.
entryv
[
jhi
-
1
]
.
Hi_
{
// shrink right
M
.
entryv
[
jhi
-
1
]
.
Lo
=
r
.
Hi_
+
1
jhi
--
debugf_RangedMap_str
(
"
\t
shrink [%d] right
\t
-> %s
\n
"
,
jhi
-
1
,
M
)
}
if
(
jhi
-
ilo
)
>
0
{
vDeleteSlice__RangedMap_str
(
&
M
.
entryv
,
ilo
,
jhi
)
debugf_RangedMap_str
(
"
\t
delete M[%d:%d]
\t
-> %s
\n
"
,
ilo
,
jhi
,
M
)
}
// done
}
// HasRange returns whether all keys from range r belong to the map.
func
(
M
*
_RangedMap_str
)
HasRange
(
r
KeyRange
)
(
yes
bool
)
{
if
trace_RangedMap_str
{
fmt
.
Printf
(
"
\n\n
HasRange:
\n
"
)
fmt
.
Printf
(
" M: %s
\n
"
,
M
)
fmt
.
Printf
(
" r: %s
\n
"
,
r
)
defer
func
()
{
fmt
.
Printf
(
"->·: %v
\n
"
,
yes
)
}()
}
M
.
verify
()
// find first ilo: r.lo < [ilo].hi
l
:=
len
(
M
.
entryv
)
ilo
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
r
.
Lo
<=
M
.
entryv
[
i
]
.
Hi_
})
debugf_RangedMap_str
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
// not found
return
false
}
// all keys from r are in M if r ∈ [ilo] XXX not in case of different values
return
(
M
.
entryv
[
ilo
]
.
Lo
<=
r
.
Lo
&&
r
.
Hi_
<=
M
.
entryv
[
ilo
]
.
Hi_
)
}
// --------
// verify checks _RangedMap_str for internal consistency:
// - ranges must be not overlapping and ↑
// - adjacent ranges must map to different values
func
(
M
*
_RangedMap_str
)
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
:=
"M.verify: fail:
\n\n
"
for
_
,
bad
:=
range
badv
{
emsg
+=
fmt
.
Sprintf
(
"- %s
\n
"
,
bad
)
}
emsg
+=
fmt
.
Sprintf
(
"
\n
S: %s
\n
"
,
M
)
panic
(
emsg
)
}
}()
hi_Prev
:=
KeyMin
var
v_Prev
string
for
i
,
e
:=
range
M
.
entryv
{
hiPrev
:=
hi_Prev
+
1
if
i
>
0
{
if
(
e
.
Value
==
v_Prev
)
{
if
!
(
hiPrev
<
e
.
Lo
)
{
// NOTE not ≤ - adjacent ranges must be merged
badf
(
"[%d]: same value: !(hiPrev < e.lo)"
,
i
)
}
}
else
{
if
!
(
hi_Prev
<=
e
.
Lo
)
{
badf
(
"[%d]: different value: !(hiPrev ≤ e.lo)"
,
i
)
}
}
}
if
!
(
e
.
Lo
<=
e
.
Hi_
)
{
badf
(
"[%d]: !(e.lo ≤ e.hi_)"
,
i
)
}
hi_Prev
=
e
.
Hi_
v_Prev
=
e
.
Value
}
}
// Clone returns copy of the map.
//
// NOTE values are _not_ cloned.
func
(
orig
*
_RangedMap_str
)
Clone
()
*
_RangedMap_str
{
klon
:=
&
_RangedMap_str
{}
klon
.
entryv
=
append
(
klon
.
entryv
,
orig
.
entryv
...
)
return
klon
}
// Empty returns whether the map is empty.
func
(
M
*
_RangedMap_str
)
Empty
()
bool
{
return
len
(
M
.
entryv
)
==
0
}
// Equal returns whether A == B.
func
(
A
*
_RangedMap_str
)
Equal
(
B
*
_RangedMap_str
)
bool
{
if
len
(
A
.
entryv
)
!=
len
(
B
.
entryv
)
{
return
false
}
for
i
,
ea
:=
range
A
.
entryv
{
eb
:=
B
.
entryv
[
i
]
if
ea
!=
eb
{
return
false
}
}
return
true
}
// Clear removes all elements from the map.
func
(
M
*
_RangedMap_str
)
Clear
()
{
M
.
entryv
=
nil
}
// AllRanges returns slice of all key ranges in the set.
//
// TODO -> iter?
func
(
M
*
_RangedMap_str
)
AllRanges
()
/*readonly*/
[]
_RangedMap_strEntry
{
return
M
.
entryv
}
// XXX -> ptr?
func
(
M
_RangedMap_str
)
String
()
string
{
s
:=
"{"
for
i
,
e
:=
range
M
.
entryv
{
if
i
>
0
{
s
+=
" "
}
s
+=
e
.
String
()
}
s
+=
"}"
return
s
}
func
(
e
*
_RangedMap_strEntry
)
String
()
string
{
s
:=
e
.
KeyRange
.
String
()
v
:=
fmt
.
Sprintf
(
"%v"
,
e
.
Value
)
if
v
!=
""
{
// omit ":<v>" in the case of set
s
+=
":"
+
v
}
return
s
}
func
debugf_RangedMap_str
(
format
string
,
argv
...
interface
{})
{
if
!
debug_RangedMap_str
{
return
}
fmt
.
Printf
(
format
,
argv
...
)
}
// ---- slice ops ----
// vInsert__RangedMap_str inserts e into *pv[i].
func
vInsert__RangedMap_str
(
pv
*
[]
_RangedMap_strEntry
,
i
int
,
e
_RangedMap_strEntry
)
{
v
:=
*
pv
v
=
append
(
v
,
_RangedMap_strEntry
{})
copy
(
v
[
i
+
1
:
],
v
[
i
:
])
v
[
i
]
=
e
*
pv
=
v
}
// vDeleteSlice__RangedMap_str deletes *pv[lo:hi].
func
vDeleteSlice__RangedMap_str
(
pv
*
[]
_RangedMap_strEntry
,
lo
,
hi
int
)
{
v
:=
*
pv
n
:=
copy
(
v
[
lo
:
],
v
[
hi
:
])
v
=
v
[
:
lo
+
n
]
*
pv
=
v
}
// vReplaceSlice__RangedMap_str replaces *pv[lo:hi] with e.
func
vReplaceSlice__RangedMap_str
(
pv
*
[]
_RangedMap_strEntry
,
lo
,
hi
int
,
e
_RangedMap_strEntry
)
{
v
:=
*
pv
n
:=
copy
(
v
[
lo
+
1
:
],
v
[
hi
:
])
v
[
lo
]
=
e
v
=
v
[
:
lo
+
1
+
n
]
*
pv
=
v
}
wcfs/internal/xbtree/blib/zrangemap_void.go
View file @
0aff75b0
...
@@ -155,8 +155,8 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
...
@@ -155,8 +155,8 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
// if [r.lo,r.hi) was outside of any entry - create new entry
// if [r.lo,r.hi) was outside of any entry - create new entry
if
r
.
Hi_
<
M
.
entryv
[
ilo
]
.
Lo
{
if
r
.
Hi_
<
M
.
entryv
[
ilo
]
.
Lo
{
vInsert__RangedMap_void
(
&
M
.
entryv
,
ilo
,
r
)
vInsert__RangedMap_void
(
&
M
.
entryv
,
ilo
,
e
)
debugf_RangedMap_void
(
"
\t
insert %s
\t
-> %s
\n
"
,
r
,
M
)
debugf_RangedMap_void
(
"
\t
insert %s
\t
-> %s
\n
"
,
e
,
M
)
}
}
// now we have covered entries merged as needed into [ilo]
// now we have covered entries merged as needed into [ilo]
...
...
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