Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
neoppod
Commits
5404250a
Commit
5404250a
authored
Feb 14, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
dacbb6cf
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
190 additions
and
109 deletions
+190
-109
t/neo/storage/fs1/index.go
t/neo/storage/fs1/index.go
+190
-109
No files found.
t/neo/storage/fs1/index.go
View file @
5404250a
...
...
@@ -16,9 +16,14 @@
package
fs1
import
(
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
"net"
"os"
"strconv"
"../../zodb"
"./fsb"
...
...
@@ -73,6 +78,8 @@ func (fsi *fsIndex) Save(topPos int64, w io.Writer) error {
p
:=
pickle
.
NewEncoder
(
w
)
err
:=
p
.
Encode
(
topPos
)
{
if
err
!=
nil
{
goto
out
}
...
...
@@ -84,7 +91,6 @@ func (fsi *fsIndex) Save(topPos int64, w io.Writer) error {
posBuf
:=
[]
byte
{}
// current pos[0:6]pos[0:6]...
var
t
[
2
]
interface
{}
// tuple for (oid, fsBucket.toString())
e
,
err
:=
fsi
.
SeekFirst
()
if
err
==
io
.
EOF
{
// always only io.EOF indicating an empty btree
goto
skip
...
...
@@ -123,15 +129,16 @@ func (fsi *fsIndex) Save(topPos int64, w io.Writer) error {
e
.
Close
()
skip
:
skip
:
err
=
p
.
Encode
(
pickle
.
None
{})
}
out
:
if
err
==
nil
{
return
err
}
if
_
,
ok
:=
err
.
(
pi
kle
.
TypeError
);
ok
{
if
_
,
ok
:=
err
.
(
*
pic
kle
.
TypeError
);
ok
{
panic
(
err
)
// all our types are expected to be supported by pickle
}
...
...
@@ -140,26 +147,42 @@ out:
return
&
IndexIOError
{
"save"
,
err
}
}
// IndexLoadError is the errortype returned by index load routines
type
IndexLoadError
struct
{
Filename
string
Pos
int64
Err
error
}
func
(
e
*
IndexLoadError
)
Error
()
string
{
s
:=
e
.
Filename
if
s
!=
""
{
s
+=
": "
}
s
+=
"pickle @"
+
strconv
.
FormatInt
(
e
.
Pos
,
10
)
+
": "
s
+=
e
.
Err
.
Error
()
return
s
}
// LoadIndex loads index from a reader
func
LoadIndex
(
r
io
.
Reader
)
(
topPos
int64
,
fsi
*
fsIndex
,
err
error
)
{
p
:=
pickle
.
NewDecoder
(
r
)
// if we can know file position we can show it in error context
rseek
,
_
:=
r
.
(
io
.
Seeker
)
var
rpos
int64
decode
:=
func
()
(
interface
{},
error
)
{
if
rseek
!=
nil
{
rpos
=
rseek
.
Seek
(
...
)
// XXX not ok as p buffers r internally
}
}
xr
:=
NewBufReader
(
r
)
// by passing bufio.Reader directly we make sure it won't create one internally
p
:=
pickle
.
NewDecoder
(
xr
.
Reader
)
var
picklePos
int64
{
picklePos
=
xr
.
InputOffset
()
xtopPos
,
err
:=
p
.
Decode
()
if
err
!=
nil
{
// TODO err
goto
out
}
topPos
,
ok
:=
xtopPos
.
(
int64
)
var
ok
bool
topPos
,
ok
=
xtopPos
.
(
int64
)
if
!
ok
{
// TODO err
err
=
fmt
.
Errorf
(
"topPos is %T (expected int64)"
,
xtopPos
)
goto
out
}
fsi
=
&
fsIndex
{}
// TODO cmpFunc ...
...
...
@@ -168,14 +191,17 @@ func LoadIndex(r io.Reader) (topPos int64, fsi *fsIndex, err error) {
loop
:
for
{
// load/decode next entry
picklePos
=
xr
.
InputOffset
()
xv
,
err
:=
p
.
Decode
()
if
err
!=
nil
{
// TODO err
goto
out
}
switch
xv
.
(
type
)
{
default
:
// TODO err
break
err
=
fmt
.
Errorf
(
"invalid entry: type %T"
,
xv
)
goto
out
case
pickle
.
None
:
break
loop
...
...
@@ -184,25 +210,40 @@ loop:
// so far ok
}
// unpack entry tuple -> oidPrefix, fsBucket
v
:=
xv
.
([]
interface
{})
if
len
(
v
)
!=
2
{
// TODO err
err
=
fmt
.
Errorf
(
"invalid entry: len = %i"
,
len
(
v
))
goto
out
}
// decode oidPrefix
xoidPrefixStr
:=
v
[
0
]
oidPrefixStr
,
ok
:=
xoidPrefixStr
.
(
string
)
if
!
ok
||
len
(
oidPrefixStr
)
!=
6
{
// TODO
if
!
ok
{
err
=
fmt
.
Errorf
(
"invalid oidPrefix: type %T"
,
xoidPrefixStr
)
goto
out
}
if
l
:=
len
(
oidPrefixStr
);
l
!=
6
{
err
=
fmt
.
Errorf
(
"invalid oidPrefix: len = %i"
,
l
)
goto
out
}
copy
(
oidb
[
:
],
oidPrefixStr
)
oidPrefix
:=
zodb
.
Oid
(
binary
.
BigEndian
.
Uint64
(
oidb
[
:
]))
// check fsBucket
xkvStr
:=
v
[
1
]
kvStr
,
ok
:=
xkvStr
.
(
string
)
if
!
ok
||
len
(
kvStr
)
%
8
!=
0
{
// TODO
if
!
ok
{
err
=
fmt
.
Errorf
(
"invalid fsBucket: type %T"
,
xkvStr
)
goto
out
}
if
l
:=
len
(
kvStr
);
l
%
8
!=
0
{
err
=
fmt
.
Errorf
(
"invalid fsBucket: len = %i"
,
l
)
goto
out
}
// load btree from fsBucket entries
kvBuf
:=
mem
.
Bytes
(
kvStr
)
n
:=
len
(
kvBuf
)
/
8
...
...
@@ -213,26 +254,66 @@ loop:
oid
:=
zodb
.
Oid
(
binary
.
BigEndian
.
Uint16
(
oidBuf
[
i
*
2
:
]))
oid
|=
oidPrefix
copy
(
posb
[
2
:
],
posBuf
[
i
*
6
:
])
tid
:=
zodb
.
Tid
(
binary
.
BigEndian
.
Uint64
(
posb
[
:
]))
pos
:=
int64
(
binary
.
BigEndian
.
Uint64
(
posb
[
:
]))
fsi
.
Set
(
oid
,
tid
)
fsi
.
Set
(
oid
,
pos
)
}
}
}
return
topPos
,
fsi
,
nil
out
:
if
err
==
nil
{
return
topPos
,
fsi
,
err
}
rname
:=
IOName
(
r
)
return
0
,
nil
,
&
IndexLoadError
{
IOName
(
r
),
picklePos
,
err
}
}
// CountReader is an io.Reader that count total bytes read.
type
CountReader
struct
{
io
.
Reader
nread
int64
}
// same for file name
rname
,
_
:=
r
.
(
interface
{
Name
()
string
})
func
(
r
*
CountReader
)
Read
(
p
[]
byte
)
(
int
,
error
)
{
n
,
err
:=
r
.
Reader
.
Read
(
p
)
r
.
nread
+=
int64
(
n
)
return
n
,
err
}
// InputOffset returns current position in input stream
func
(
r
*
CountReader
)
InputOffset
()
int64
{
return
r
.
nread
}
// BufReader is a bufio.Reader + bell & whistles
type
BufReader
struct
{
*
bufio
.
Reader
cr
*
CountReader
}
func
NewBufReader
(
r
io
.
Reader
)
*
BufReader
{
// idempotent(BufReader)
if
r
,
ok
:=
r
.
(
*
BufReader
);
ok
{
return
r
}
// idempotent(CountReader)
cr
,
ok
:=
r
.
(
*
CountReader
)
if
!
ok
{
cr
=
&
CountReader
{
r
,
0
}
}
return
&
BufReader
{
bufio
.
NewReader
(
cr
),
cr
}
}
// InputOffset returns current position in input stream
func
(
r
*
BufReader
)
InputOffset
()
int64
{
return
r
.
cr
.
InputOffset
()
-
int64
(
r
.
Reader
.
Buffered
())
}
// IOName returns a "filename" associated with io.Reader, io.Writer, net.Conn, ...
// if name cannot be deterined - "" is returned.
...
...
@@ -245,14 +326,14 @@ func IOName(f interface {}) string {
case
net
.
Conn
:
// XXX not including LocalAddr is ok?
return
f
.
RemoteAddr
.
String
()
return
f
.
RemoteAddr
()
.
String
()
case
*
io
.
LimitedReader
:
return
IOName
(
f
.
R
)
case
*
io
.
PipeReader
:
fallthrough
return
"pipe"
case
*
io
.
PipeWriter
:
return
"pipe"
...
...
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