Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
git-backup
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
git-backup
Commits
0be1f647
Commit
0be1f647
authored
Dec 13, 2016
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move string <-> []byte zero-copy conversion routines to
https://lab.nexedi.com/kirr/go123/mem/
It is now mem.String(), and mem.Bytes()
parent
3aedc246
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
18 additions
and
47 deletions
+18
-47
git-backup.go
git-backup.go
+5
-4
git.go
git.go
+3
-2
gitobjects.go
gitobjects.go
+3
-2
sha1.go
sha1.go
+4
-2
util.go
util.go
+3
-22
util_test.go
util_test.go
+0
-15
No files found.
git-backup.go
View file @
0be1f647
...
...
@@ -76,6 +76,7 @@ import (
"time"
"lab.nexedi.com/kirr/go123/exc"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/go123/myname"
"lab.nexedi.com/kirr/go123/xerr"
...
...
@@ -131,7 +132,7 @@ func file_to_blob(g *git.Repository, path string) (Sha1, uint32) {
if
st
.
Mode
&
syscall
.
S_IFMT
==
syscall
.
S_IFLNK
{
__
,
err
:=
os
.
Readlink
(
path
)
blob_content
=
Bytes
(
__
)
blob_content
=
mem
.
Bytes
(
__
)
exc
.
Raiseif
(
err
)
}
else
{
blob_content
,
err
=
ioutil
.
ReadFile
(
path
)
...
...
@@ -154,7 +155,7 @@ func blob_to_file(g *git.Repository, blob_sha1 Sha1, mode uint32, path string) {
exc
.
Raiseif
(
err
)
if
mode
&
syscall
.
S_IFMT
==
syscall
.
S_IFLNK
{
err
=
os
.
Symlink
(
String
(
blob_content
),
path
)
err
=
os
.
Symlink
(
mem
.
String
(
blob_content
),
path
)
exc
.
Raiseif
(
err
)
}
else
{
// NOTE mode is native - we cannot use ioutil.WriteFile() directly
...
...
@@ -192,7 +193,7 @@ func obj_represent_as_commit(g *git.Repository, sha1 Sha1, obj_type string) Sha1
tag
,
tag_obj
:=
xload_tag
(
g
,
sha1
)
tagged_type
=
tag
.
tagged_type
tagged_sha1
=
tag
.
tagged_sha1
obj_encoded
+=
String
(
tag_obj
.
Data
())
obj_encoded
+=
mem
.
String
(
tag_obj
.
Data
())
}
else
{
// for tree/blob we only care that object stays reachable
tagged_type
=
obj_type
...
...
@@ -276,7 +277,7 @@ func obj_recreate_from_commit(g *git.Repository, commit_sha1 Sha1) Sha1 {
}
// re-create tag object
tag_sha1
,
err
:=
WriteObject
(
g
,
Bytes
(
obj_raw
),
git
.
ObjectTag
)
tag_sha1
,
err
:=
WriteObject
(
g
,
mem
.
Bytes
(
obj_raw
),
git
.
ObjectTag
)
exc
.
Raiseif
(
err
)
// the original tagged object should be already in repository, because we
...
...
git.go
View file @
0be1f647
...
...
@@ -21,6 +21,7 @@ import (
"strings"
"lab.nexedi.com/kirr/go123/exc"
"lab.nexedi.com/kirr/go123/mem"
)
// how/whether to redirect stdio of spawned process
...
...
@@ -78,8 +79,8 @@ func _git(argv []string, ctx RunWith) (err error, stdout, stderr string) {
}
err
=
cmd
.
Run
()
stdout
=
String
(
stdoutBuf
.
Bytes
())
stderr
=
String
(
stderrBuf
.
Bytes
())
stdout
=
mem
.
String
(
stdoutBuf
.
Bytes
())
stderr
=
mem
.
String
(
stderrBuf
.
Bytes
())
if
!
ctx
.
raw
{
// prettify stdout (e.g. so that 'sha1\n' becomes 'sha1' and can be used directly
...
...
gitobjects.go
View file @
0be1f647
...
...
@@ -22,6 +22,7 @@ import (
"time"
"lab.nexedi.com/kirr/go123/exc"
"lab.nexedi.com/kirr/go123/mem"
git
"github.com/libgit2/git2go"
)
...
...
@@ -100,7 +101,7 @@ func xload_tag(g *git.Repository, tag_sha1 Sha1) (tag *Tag, tag_obj *git.OdbObje
tag_obj
,
err
:=
ReadObject
(
g
,
tag_sha1
,
git
.
ObjectTag
)
exc
.
Raiseif
(
err
)
tag
,
err
=
tag_parse
(
String
(
tag_obj
.
Data
()))
tag
,
err
=
tag_parse
(
mem
.
String
(
tag_obj
.
Data
()))
if
err
!=
nil
{
exc
.
Raise
(
&
TagLoadError
{
tag_sha1
,
err
})
}
...
...
@@ -226,7 +227,7 @@ func xcommit_tree2(g *git.Repository, tree Sha1, parents []Sha1, msg string, aut
commit
+=
fmt
.
Sprintf
(
"committer %s
\n
"
,
&
committer
)
commit
+=
fmt
.
Sprintf
(
"
\n
%s"
,
msg
)
sha1
,
err
:=
WriteObject
(
g
,
Bytes
(
commit
),
git
.
ObjectCommit
)
sha1
,
err
:=
WriteObject
(
g
,
mem
.
Bytes
(
commit
),
git
.
ObjectCommit
)
exc
.
Raiseif
(
err
)
return
sha1
...
...
sha1.go
View file @
0be1f647
...
...
@@ -18,6 +18,8 @@ import (
"encoding/hex"
"fmt"
"lab.nexedi.com/kirr/go123/mem"
git
"github.com/libgit2/git2go"
)
...
...
@@ -45,7 +47,7 @@ func Sha1Parse(sha1str string) (Sha1, error) {
if
hex
.
DecodedLen
(
len
(
sha1str
))
!=
SHA1_RAWSIZE
{
return
Sha1
{},
fmt
.
Errorf
(
"sha1parse: %q invalid"
,
sha1str
)
}
_
,
err
:=
hex
.
Decode
(
sha1
.
sha1
[
:
],
Bytes
(
sha1str
))
_
,
err
:=
hex
.
Decode
(
sha1
.
sha1
[
:
],
mem
.
Bytes
(
sha1str
))
if
err
!=
nil
{
return
Sha1
{},
fmt
.
Errorf
(
"sha1parse: %q invalid: %s"
,
sha1str
,
err
)
}
...
...
@@ -68,7 +70,7 @@ func (sha1 *Sha1) Scan(s fmt.ScanState, ch rune) error {
return
err
}
*
sha1
,
err
=
Sha1Parse
(
String
(
tok
))
*
sha1
,
err
=
Sha1Parse
(
mem
.
String
(
tok
))
return
err
}
...
...
util.go
View file @
0be1f647
...
...
@@ -17,32 +17,13 @@ import (
"encoding/hex"
"fmt"
"os"
"reflect"
"strings"
"syscall"
"unicode"
"unicode/utf8"
"unsafe"
)
// string -> []byte without copying
func
Bytes
(
s
string
)
[]
byte
{
var
b
[]
byte
bp
:=
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
&
b
))
bp
.
Data
=
(
*
reflect
.
StringHeader
)(
unsafe
.
Pointer
(
&
s
))
.
Data
bp
.
Cap
=
len
(
s
)
bp
.
Len
=
len
(
s
)
return
b
}
// []byte -> string without copying
func
String
(
b
[]
byte
)
string
{
var
s
string
sp
:=
(
*
reflect
.
StringHeader
)(
unsafe
.
Pointer
(
&
s
))
sp
.
Data
=
(
*
reflect
.
SliceHeader
)(
unsafe
.
Pointer
(
&
b
))
.
Data
sp
.
Len
=
len
(
b
)
return
s
}
"lab.nexedi.com/kirr/go123/mem"
)
// split string into lines. The last line, if it is empty, is omitted from the result
// (rationale is: string.Split("hello\nworld\n", "\n") -> ["hello", "world", ""])
...
...
@@ -212,7 +193,7 @@ func path_refunescape(s string) (string, error) {
}
out
=
append
(
out
,
c
)
}
return
String
(
out
),
nil
return
mem
.
String
(
out
),
nil
}
type
EscapeError
string
...
...
util_test.go
View file @
0be1f647
...
...
@@ -18,21 +18,6 @@ import (
"testing"
)
// check that String() and Bytes() create correct objects which alias original object memory
func
TestStringBytes
(
t
*
testing
.
T
)
{
s
:=
"Hello"
b
:=
[]
byte
(
s
)
s1
:=
String
(
b
)
b1
:=
Bytes
(
s1
)
if
s1
!=
s
{
t
.
Error
(
"string -> []byte -> String != Identity"
)
}
if
!
reflect
.
DeepEqual
(
b1
,
b
)
{
t
.
Error
(
"[]byte -> String -> Bytes != Identity"
)
}
b
[
0
]
=
'I'
if
s
!=
"Hello"
{
t
.
Error
(
"string -> []byte not copied"
)
}
if
s1
!=
"Iello"
{
t
.
Error
(
"[]byte -> String not aliased"
)
}
if
!
reflect
.
DeepEqual
(
b1
,
b
)
{
t
.
Error
(
"string -> Bytes not aliased"
)
}
}
func
TestSplitLines
(
t
*
testing
.
T
)
{
var
tests
=
[]
struct
{
input
,
sep
string
;
output
[]
string
}
{
{
""
,
"
\n
"
,
[]
string
{}},
...
...
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