Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
f1809812
Commit
f1809812
authored
Mar 15, 2019
by
Janoš Guljaš
Committed by
Anton Evangelatov
Mar 15, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
swarm/shed: add vector uint64 field (#19279)
parent
4b4f03ca
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
458 additions
and
0 deletions
+458
-0
vector_uint64.go
swarm/shed/vector_uint64.go
+146
-0
vector_uint64_test.go
swarm/shed/vector_uint64_test.go
+312
-0
No files found.
swarm/shed/vector_uint64.go
0 → 100644
View file @
f1809812
// Copyright 2018 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
shed
import
(
"encoding/binary"
"github.com/syndtr/goleveldb/leveldb"
)
// Uint64Vector provides a way to have multiple counters in the database.
// It transparently encodes uint64 type value to bytes.
type
Uint64Vector
struct
{
db
*
DB
key
[]
byte
}
// NewUint64Vector returns a new Uint64Vector.
// It validates its name and type against the database schema.
func
(
db
*
DB
)
NewUint64Vector
(
name
string
)
(
f
Uint64Vector
,
err
error
)
{
key
,
err
:=
db
.
schemaFieldKey
(
name
,
"vector-uint64"
)
if
err
!=
nil
{
return
f
,
err
}
return
Uint64Vector
{
db
:
db
,
key
:
key
,
},
nil
}
// Get retrieves a uint64 value at index i from the database.
// If the value is not found in the database a 0 value
// is returned and no error.
func
(
f
Uint64Vector
)
Get
(
i
uint64
)
(
val
uint64
,
err
error
)
{
b
,
err
:=
f
.
db
.
Get
(
f
.
indexKey
(
i
))
if
err
!=
nil
{
if
err
==
leveldb
.
ErrNotFound
{
return
0
,
nil
}
return
0
,
err
}
return
binary
.
BigEndian
.
Uint64
(
b
),
nil
}
// Put encodes uin64 value and stores it in the database.
func
(
f
Uint64Vector
)
Put
(
i
,
val
uint64
)
(
err
error
)
{
return
f
.
db
.
Put
(
f
.
indexKey
(
i
),
encodeUint64
(
val
))
}
// PutInBatch stores a uint64 value at index i in a batch
// that can be saved later in the database.
func
(
f
Uint64Vector
)
PutInBatch
(
batch
*
leveldb
.
Batch
,
i
,
val
uint64
)
{
batch
.
Put
(
f
.
indexKey
(
i
),
encodeUint64
(
val
))
}
// Inc increments a uint64 value in the database.
// This operation is not goroutine safe.
func
(
f
Uint64Vector
)
Inc
(
i
uint64
)
(
val
uint64
,
err
error
)
{
val
,
err
=
f
.
Get
(
i
)
if
err
!=
nil
{
if
err
==
leveldb
.
ErrNotFound
{
val
=
0
}
else
{
return
0
,
err
}
}
val
++
return
val
,
f
.
Put
(
i
,
val
)
}
// IncInBatch increments a uint64 value at index i in the batch
// by retreiving a value from the database, not the same batch.
// This operation is not goroutine safe.
func
(
f
Uint64Vector
)
IncInBatch
(
batch
*
leveldb
.
Batch
,
i
uint64
)
(
val
uint64
,
err
error
)
{
val
,
err
=
f
.
Get
(
i
)
if
err
!=
nil
{
if
err
==
leveldb
.
ErrNotFound
{
val
=
0
}
else
{
return
0
,
err
}
}
val
++
f
.
PutInBatch
(
batch
,
i
,
val
)
return
val
,
nil
}
// Dec decrements a uint64 value at index i in the database.
// This operation is not goroutine safe.
// The field is protected from overflow to a negative value.
func
(
f
Uint64Vector
)
Dec
(
i
uint64
)
(
val
uint64
,
err
error
)
{
val
,
err
=
f
.
Get
(
i
)
if
err
!=
nil
{
if
err
==
leveldb
.
ErrNotFound
{
val
=
0
}
else
{
return
0
,
err
}
}
if
val
!=
0
{
val
--
}
return
val
,
f
.
Put
(
i
,
val
)
}
// DecInBatch decrements a uint64 value at index i in the batch
// by retreiving a value from the database, not the same batch.
// This operation is not goroutine safe.
// The field is protected from overflow to a negative value.
func
(
f
Uint64Vector
)
DecInBatch
(
batch
*
leveldb
.
Batch
,
i
uint64
)
(
val
uint64
,
err
error
)
{
val
,
err
=
f
.
Get
(
i
)
if
err
!=
nil
{
if
err
==
leveldb
.
ErrNotFound
{
val
=
0
}
else
{
return
0
,
err
}
}
if
val
!=
0
{
val
--
}
f
.
PutInBatch
(
batch
,
i
,
val
)
return
val
,
nil
}
// indexKey concatenates field prefix and vector index
// returning a unique database key for a specific vector element.
func
(
f
Uint64Vector
)
indexKey
(
i
uint64
)
(
key
[]
byte
)
{
b
:=
make
([]
byte
,
8
)
binary
.
BigEndian
.
PutUint64
(
b
,
i
)
return
append
(
f
.
key
,
b
...
)
}
swarm/shed/vector_uint64_test.go
0 → 100644
View file @
f1809812
// Copyright 2018 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
shed
import
(
"testing"
"github.com/syndtr/goleveldb/leveldb"
)
// TestUint64Vector validates put and get operations
// of the Uint64Vector.
func
TestUint64Vector
(
t
*
testing
.
T
)
{
db
,
cleanupFunc
:=
newTestDB
(
t
)
defer
cleanupFunc
()
bins
,
err
:=
db
.
NewUint64Vector
(
"bins"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
t
.
Run
(
"get empty"
,
func
(
t
*
testing
.
T
)
{
got
,
err
:=
bins
.
Get
(
0
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
var
want
uint64
if
got
!=
want
{
t
.
Errorf
(
"got uint64 %v, want %v"
,
got
,
want
)
}
})
t
.
Run
(
"put"
,
func
(
t
*
testing
.
T
)
{
for
_
,
index
:=
range
[]
uint64
{
0
,
1
,
2
,
5
,
100
}
{
var
want
uint64
=
42
+
index
err
=
bins
.
Put
(
index
,
want
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
:=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
t
.
Run
(
"overwrite"
,
func
(
t
*
testing
.
T
)
{
var
want
uint64
=
84
+
index
err
=
bins
.
Put
(
index
,
want
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
:=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
})
}
})
t
.
Run
(
"put in batch"
,
func
(
t
*
testing
.
T
)
{
for
_
,
index
:=
range
[]
uint64
{
0
,
1
,
2
,
3
,
5
,
10
}
{
batch
:=
new
(
leveldb
.
Batch
)
var
want
uint64
=
43
+
index
bins
.
PutInBatch
(
batch
,
index
,
want
)
err
=
db
.
WriteBatch
(
batch
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
:=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
t
.
Run
(
"overwrite"
,
func
(
t
*
testing
.
T
)
{
batch
:=
new
(
leveldb
.
Batch
)
var
want
uint64
=
85
+
index
bins
.
PutInBatch
(
batch
,
index
,
want
)
err
=
db
.
WriteBatch
(
batch
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
:=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
})
}
})
}
// TestUint64Vector_Inc validates Inc operation
// of the Uint64Vector.
func
TestUint64Vector_Inc
(
t
*
testing
.
T
)
{
db
,
cleanupFunc
:=
newTestDB
(
t
)
defer
cleanupFunc
()
bins
,
err
:=
db
.
NewUint64Vector
(
"bins"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
for
_
,
index
:=
range
[]
uint64
{
0
,
1
,
2
,
3
,
5
,
10
}
{
var
want
uint64
=
1
got
,
err
:=
bins
.
Inc
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
want
=
2
got
,
err
=
bins
.
Inc
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
}
}
// TestUint64Vector_IncInBatch validates IncInBatch operation
// of the Uint64Vector.
func
TestUint64Vector_IncInBatch
(
t
*
testing
.
T
)
{
db
,
cleanupFunc
:=
newTestDB
(
t
)
defer
cleanupFunc
()
bins
,
err
:=
db
.
NewUint64Vector
(
"bins"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
for
_
,
index
:=
range
[]
uint64
{
0
,
1
,
2
,
3
,
5
,
10
}
{
batch
:=
new
(
leveldb
.
Batch
)
var
want
uint64
=
1
got
,
err
:=
bins
.
IncInBatch
(
batch
,
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
err
=
db
.
WriteBatch
(
batch
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
batch2
:=
new
(
leveldb
.
Batch
)
want
=
2
got
,
err
=
bins
.
IncInBatch
(
batch2
,
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
err
=
db
.
WriteBatch
(
batch2
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
}
}
// TestUint64Vector_Dec validates Dec operation
// of the Uint64Vector.
func
TestUint64Vector_Dec
(
t
*
testing
.
T
)
{
db
,
cleanupFunc
:=
newTestDB
(
t
)
defer
cleanupFunc
()
bins
,
err
:=
db
.
NewUint64Vector
(
"bins"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
for
_
,
index
:=
range
[]
uint64
{
0
,
1
,
2
,
3
,
5
,
10
}
{
// test overflow protection
var
want
uint64
got
,
err
:=
bins
.
Dec
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
want
=
32
+
index
err
=
bins
.
Put
(
index
,
want
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
want
=
31
+
index
got
,
err
=
bins
.
Dec
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
}
}
// TestUint64Vector_DecInBatch validates DecInBatch operation
// of the Uint64Vector.
func
TestUint64Vector_DecInBatch
(
t
*
testing
.
T
)
{
db
,
cleanupFunc
:=
newTestDB
(
t
)
defer
cleanupFunc
()
bins
,
err
:=
db
.
NewUint64Vector
(
"bins"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
for
_
,
index
:=
range
[]
uint64
{
0
,
1
,
2
,
3
,
5
,
10
}
{
batch
:=
new
(
leveldb
.
Batch
)
var
want
uint64
got
,
err
:=
bins
.
DecInBatch
(
batch
,
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
err
=
db
.
WriteBatch
(
batch
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
batch2
:=
new
(
leveldb
.
Batch
)
want
=
42
+
index
bins
.
PutInBatch
(
batch2
,
index
,
want
)
err
=
db
.
WriteBatch
(
batch2
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
batch3
:=
new
(
leveldb
.
Batch
)
want
=
41
+
index
got
,
err
=
bins
.
DecInBatch
(
batch3
,
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
err
=
db
.
WriteBatch
(
batch3
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
got
,
err
=
bins
.
Get
(
index
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
got
!=
want
{
t
.
Errorf
(
"got %v uint64 %v, want %v"
,
index
,
got
,
want
)
}
}
}
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