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
a6bac322
Commit
a6bac322
authored
Sep 27, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
7829c494
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
463 additions
and
26 deletions
+463
-26
wcfs/internal/xbtree/blib/gen-rangemap
wcfs/internal/xbtree/blib/gen-rangemap
+11
-10
wcfs/internal/xbtree/blib/rangemap.go.in
wcfs/internal/xbtree/blib/rangemap.go.in
+11
-14
wcfs/internal/xbtree/blib/rangeset.go
wcfs/internal/xbtree/blib/rangeset.go
+5
-2
wcfs/internal/xbtree/blib/zrangemap_void.go
wcfs/internal/xbtree/blib/zrangemap_void.go
+436
-0
No files found.
wcfs/internal/xbtree/blib/gen-rangemap
View file @
a6bac322
#!/bin/bash -e
# rangemap.go.in -> specialized with concrete types
# gen-rangemap
KIND
VALUE out
# gen-rangemap
TYPE
VALUE out
# Copyright (C) 2018-2021 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
...
...
@@ -21,7 +21,7 @@
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
KIND
=
$1
TYPE
=
$1
VALUE
=
$2
out
=
$3
...
...
@@ -30,7 +30,7 @@ Value=${VALUE^}
input
=
$(
dirname
$0
)
/rangemap.go.in
echo
"// Code generated by gen-rangemap; DO NOT EDIT."
>
$out
echo
"// Code generated by gen-rangemap
$TYPE
$VALUE
; DO NOT EDIT."
>
$out
echo
>>
$out
sed
\
...
...
@@ -38,11 +38,12 @@ sed \
-e
"s/<KIND>/
$KIND
/g"
\
-e
"s/VALUE/
$VALUE
/g"
\
-e
"s/<Value>/
$Value
/g"
\
-e
"s/
\b
Node
\b
/
${
KIND
}
Node/g"
\
-e
"s/
\b
BTree
\b
/
${
KIND
}
BTree/g"
\
-e
"s/
\b
Entry
\b
/
${
KIND
}
Entry/g"
\
-e
"s/
\b
Bucket
\b
/
${
KIND
}
Bucket/g"
\
-e
"s/
\b
BucketEntry
\b
/
${
KIND
}
BucketEntry/g"
\
-e
"s/
\b
btreeState
\b
/
${
kind
}
btreeState/g"
\
-e
"s/
\b
bucketState
\b
/
${
kind
}
bucketState/g"
\
-e
"s/
\b
RangedMap
\b
/
${
TYPE
}
/g"
\
-e
"s/
\b
RangedMapEntry
\b
/
${
TYPE
}
Entry/g"
\
-e
"s/
\b
vInsert
\b
/vInsert_
${
TYPE
}
/g"
\
-e
"s/
\b
vDeleteSlice
\b
/vDeleteSlice_
${
TYPE
}
/g"
\
-e
"s/
\b
vReplaceSlice
\b
/vReplaceSlice_
${
TYPE
}
/g"
\
-e
"s/
\b
traceRangeMap
\b
/trace
${
TYPE
}
/g"
\
-e
"s/
\b
debugRangeMap
\b
/debug
${
TYPE
}
/g"
\
-e
"s/
\b
debugfRMap
\b
/debugf
${
TYPE
}
/g"
\
$input
>>
$out
wcfs/internal/xbtree/blib/rangemap.go.in
View file @
a6bac322
...
...
@@ -35,11 +35,11 @@ type RangedMap 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
[]
RangeMapEntry
//
lo
↑
entryv
[]
Range
d
MapEntry
//
lo
↑
}
//
RangeMapEntry
represents
one
entry
in
RangedMap
.
type
RangeMapEntry
struct
{
//
Range
d
MapEntry
represents
one
entry
in
RangedMap
.
type
Range
d
MapEntry
struct
{
KeyRange
Value
VALUE
}
...
...
@@ -102,12 +102,9 @@ func (M *RangedMap) Get_(k Key) (v VALUE, ok bool) {
return
e
.
value
,
true
}
//
SetRange
changes
M
to
map
key
range
r
to
value
v
.
func
(
M
*
RangedMap
)
SetRange
(
r
KeyRange
,
v
VALUE
)
{
e
:=
m
apEntry
{
r
,
v
}
e
:=
RangedM
apEntry
{
r
,
v
}
if
traceRangeMap
{
fmt
.
Printf
(
"
\n\n
SetRange:
\n
"
)
fmt
.
Printf
(
" M: %s
\n
"
,
M
)
...
...
@@ -370,10 +367,10 @@ func (M *RangedMap) Clear() {
M
.
entryv
=
nil
}
//
All
Entri
es
returns
slice
of
all
key
ranges
in
the
set
.
//
All
Rang
es
returns
slice
of
all
key
ranges
in
the
set
.
//
//
TODO
->
iter
?
func
(
M
*
RangedKeySet
)
All
Entries
()
/*
readonly
*/[]
Range
MapEntry
{
func
(
M
*
RangedKeySet
)
All
Ranges
()
/*
readonly
*/[]
Ranged
MapEntry
{
return
M
.
entryv
}
...
...
@@ -390,7 +387,7 @@ func (M RangedMap) String() string {
return
s
}
func
(
e
*
m
apEntry
)
String
()
string
{
func
(
e
*
RangedM
apEntry
)
String
()
string
{
s
:=
e
.
keycov
.
String
()
v
:=
fmt
.
Sprintf
(
"%v"
,
e
.
value
)
if
v
!= "" { // omit ":<v>" in the case of set
...
...
@@ -411,16 +408,16 @@ func debugfRMap(format string, argv ...interface{}) {
//
----
slice
ops
----
//
vInsert
inserts
e
into
*
pv
[
i
].
func
vInsert
(
pv
*[]
Range
MapEntry
,
i
int
,
e
Range
MapEntry
)
{
func
vInsert
(
pv
*[]
Range
dMapEntry
,
i
int
,
e
Ranged
MapEntry
)
{
v
:=
*
pv
v
=
append
(
v
,
RangeMapEntry
{})
v
=
append
(
v
,
Range
d
MapEntry
{})
copy
(
v
[
i
+
1
:],
v
[
i
:])
v
[
i
]
=
e
*
pv
=
v
}
//
vDeleteSlice
deletes
*
pv
[
lo
:
hi
].
func
vDeleteSlice
(
pv
*[]
RangeMapEntry
,
lo
,
hi
int
)
{
func
vDeleteSlice
(
pv
*[]
Range
d
MapEntry
,
lo
,
hi
int
)
{
v
:=
*
pv
n
:=
copy
(
v
[
lo
:],
v
[
hi
:])
v
=
v
[:
lo
+
n
]
...
...
@@ -428,7 +425,7 @@ func vDeleteSlice(pv *[]RangeMapEntry, lo,hi int) {
}
//
vReplaceSlice
replaces
*
pv
[
lo
:
hi
]
with
e
.
func
vReplaceSlice
(
pv
*[]
Range
MapEntry
,
lo
,
hi
int
,
e
Range
MapEntry
)
{
func
vReplaceSlice
(
pv
*[]
Range
dMapEntry
,
lo
,
hi
int
,
e
Ranged
MapEntry
)
{
v
:=
*
pv
n
:=
copy
(
v
[
lo
+
1
:],
v
[
hi
:])
v
[
lo
]
=
e
...
...
wcfs/internal/xbtree/blib/rangeset.go
View file @
a6bac322
...
...
@@ -20,16 +20,19 @@
package
blib
// set of [lo,hi) Key ranges.
//go:generate
gen-rangemap void struct{}
zrangemap_void.go
//go:generate
./gen-rangemap _RangedMap_void void
zrangemap_void.go
// RangedKeySet is set of Keys with adjacent keys coalesced into Ranges.
//
// Zero value represents empty set.
type
RangedKeySet
struct
{
m
_Ranged
Key
Map_void
// XXX naming
m
_RangedMap_void
// XXX naming
}
// void is used as value type for RangedMap to be used as set.
type
void
struct
{}
func
(
_
void
)
String
()
string
{
return
""
}
// Union returns RangedKeySet(A.keys | B.keys).
...
...
wcfs/internal/xbtree/blib/zrangemap_void.go
0 → 100644
View file @
a6bac322
// Code generated by gen-rangemap _RangedMap_void void; 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_void
=
true
const
debug_RangedMap_void
=
true
// _RangedMap_void is Key->void map with adjacent keys mapped to the same value coalesced into Ranges.
//
// Zero value represents empty map.
type
_RangedMap_void
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_voidEntry
// lo↑
}
// _RangedMap_voidEntry represents one entry in _RangedMap_void.
type
_RangedMap_voidEntry
struct
{
KeyRange
Value
void
}
// Get returns value associated with key k.
func
(
M
*
_RangedMap_void
)
Get
(
k
Key
)
void
{
v
,
_
:=
M
.
Get_
(
k
)
return
v
}
// Set changes M to map key k to value v.
func
(
M
*
_RangedMap_void
)
Set
(
k
Key
,
v
void
)
{
M
.
SetRange
(
KeyRange
{
Lo
:
k
,
Hi_
:
k
},
v
)
}
// Del removes key k.
func
(
M
*
_RangedMap_void
)
Del
(
k
Key
)
{
M
.
DelRange
(
KeyRange
{
Lo
:
k
,
Hi_
:
k
})
}
// Has returns whether key k is present in the map.
func
(
M
*
_RangedMap_void
)
Has
(
k
Key
)
bool
{
_
,
ok
:=
M
.
Get_
(
k
)
return
ok
}
// Get_ is comma-ok version of Get.
func
(
M
*
_RangedMap_void
)
Get_
(
k
Key
)
(
v
void
,
ok
bool
)
{
if
trace_RangedMap_void
{
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_void
(
"
\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_void
)
SetRange
(
r
KeyRange
,
v
void
)
{
e
:=
_RangedMap_voidEntry
{
r
,
v
}
if
trace_RangedMap_void
{
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_void
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
// not found
M
.
entryv
=
append
(
M
.
entryv
,
e
)
l
++
debugf_RangedMap_void
(
"
\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_void
(
"
\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
:=
S
.
rangev
[
ilo
]
.
Lo
hi_
:=
S
.
rangev
[
jhi
-
1
]
.
Hi_
vReplaceSlice__RangedMap_void
(
&
S
.
rangev
,
ilo
,
jhi
,
KeyRange
{
lo
,
hi_
})
debugf_RangedMap_void
(
"
\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__RangedMap_void
(
&
S
.
rangev
,
ilo
,
r
)
debugf_RangedMap_void
(
"
\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
debugf_RangedMap_void
(
"
\t
extend left
\t
-> %s
\n
"
,
S
)
}
if
r
.
Hi_
>
S
.
rangev
[
ilo
]
.
Hi_
{
S
.
rangev
[
ilo
]
.
Hi_
=
r
.
Hi_
debugf_RangedMap_void
(
"
\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
{
// XXX && .value same
vReplaceSlice__RangedMap_void
(
&
S
.
rangev
,
ilo
,
ilo
+
2
,
KeyRange
{
S
.
rangev
[
ilo
]
.
Lo
,
S
.
rangev
[
ilo
+
1
]
.
Hi_
})
debugf_RangedMap_void
(
"
\t
merge right
\t
-> %s
\n
"
,
S
)
}
}
if
ilo
>
0
{
// left
if
S
.
rangev
[
ilo
-
1
]
.
Hi_
+
1
==
S
.
rangev
[
ilo
]
.
Lo
{
// XXX && .value same
vReplaceSlice__RangedMap_void
(
&
S
.
rangev
,
ilo
-
1
,
ilo
+
1
,
KeyRange
{
S
.
rangev
[
ilo
-
1
]
.
Lo
,
S
.
rangev
[
ilo
]
.
Hi_
})
debugf_RangedMap_void
(
"
\t
merge left
\t
-> %s
\n
"
,
S
)
}
}
// done
}
// DelRange removes range r from the map.
func
(
M
*
_RangedMap_void
)
DelRange
(
r
KeyRange
)
{
if
trace_RangedMap_void
{
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_void
(
"
\t
ilo: %d
\n
"
,
ilo
)
if
ilo
==
l
{
// not found
debugf_RangedMap_void
(
"
\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_void
(
"
\t
jhi: %d
\n
"
,
jhi
)
if
jhi
==
0
{
debugf_RangedMap_void
(
"
\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_void
(
&
M
.
entryv
,
ilo
,
x
)
jhi
++
debugf_RangedMap_void
(
"
\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_void
(
"
\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_void
(
"
\t
shrink [%d] right
\t
-> %s
\n
"
,
jhi
-
1
,
M
)
}
if
(
jhi
-
ilo
)
>
0
{
vDeleteSlice__RangedMap_void
(
&
M
.
entryv
,
ilo
,
jhi
)
debugf_RangedMap_void
(
"
\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_void
)
HasRange
(
r
KeyRange
)
(
yes
bool
)
{
if
trace_RangedMap_void
{
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_void
(
"
\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_void for internal consistency:
// - ranges must be not overlapping and ↑
// - adjacent ranges must map to different values
func
(
M
*
_RangedMap_void
)
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
void
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_void
)
Clone
()
*
_RangedMap_void
{
klon
:=
&
_RangedMap_void
{}
klon
.
entryv
=
append
(
klon
.
entryv
,
orig
.
entryv
...
)
return
klon
}
// Empty returns whether the map is empty.
func
(
M
*
_RangedMap_void
)
Empty
()
bool
{
return
len
(
M
.
entryv
)
==
0
}
// Equal returns whether A == B.
func
(
A
*
_RangedMap_void
)
Equal
(
B
*
_RangedMap_void
)
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_void
)
Clear
()
{
M
.
entryv
=
nil
}
// AllRanges returns slice of all key ranges in the set.
//
// TODO -> iter?
func
(
M
*
RangedKeySet
)
AllRanges
()
/*readonly*/
[]
_RangedMap_voidEntry
{
return
M
.
entryv
}
// XXX -> ptr?
func
(
M
_RangedMap_void
)
String
()
string
{
s
:=
"{"
for
i
,
e
:=
range
M
.
entryv
{
if
i
>
0
{
s
+=
" "
}
s
+=
e
.
String
()
}
s
+=
"}"
return
s
}
func
(
e
*
_RangedMap_voidEntry
)
String
()
string
{
s
:=
e
.
keycov
.
String
()
v
:=
fmt
.
Sprintf
(
"%v"
,
e
.
value
)
if
v
!=
""
{
// omit ":<v>" in the case of set
s
+=
":"
+
v
}
return
s
}
func
debugf_RangedMap_void
(
format
string
,
argv
...
interface
{})
{
if
!
debug_RangedMap_void
{
return
}
fmt
.
Printf
(
format
,
argv
...
)
}
// ---- slice ops ----
// vInsert__RangedMap_void inserts e into *pv[i].
func
vInsert__RangedMap_void
(
pv
*
[]
_RangedMap_voidEntry
,
i
int
,
e
_RangedMap_voidEntry
)
{
v
:=
*
pv
v
=
append
(
v
,
_RangedMap_voidEntry
{})
copy
(
v
[
i
+
1
:
],
v
[
i
:
])
v
[
i
]
=
e
*
pv
=
v
}
// vDeleteSlice__RangedMap_void deletes *pv[lo:hi].
func
vDeleteSlice__RangedMap_void
(
pv
*
[]
_RangedMap_voidEntry
,
lo
,
hi
int
)
{
v
:=
*
pv
n
:=
copy
(
v
[
lo
:
],
v
[
hi
:
])
v
=
v
[
:
lo
+
n
]
*
pv
=
v
}
// vReplaceSlice__RangedMap_void replaces *pv[lo:hi] with e.
func
vReplaceSlice__RangedMap_void
(
pv
*
[]
_RangedMap_voidEntry
,
lo
,
hi
int
,
e
_RangedMap_voidEntry
)
{
v
:=
*
pv
n
:=
copy
(
v
[
lo
+
1
:
],
v
[
hi
:
])
v
[
lo
]
=
e
v
=
v
[
:
lo
+
1
+
n
]
*
pv
=
v
}
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