Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
U
utils
Project
Project
Details
Activity
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
library
utils
Commits
a3a23bc5
Verified
Commit
a3a23bc5
authored
Jan 07, 2019
by
Cui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add deep copy and Intersection
parent
928c63ad
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
232 additions
and
0 deletions
+232
-0
go.sum
go.sum
+1
-0
math.go
math.go
+37
-0
math_test.go
math_test.go
+13
-0
tools.go
tools.go
+181
-0
No files found.
go.sum
View file @
a3a23bc5
...
@@ -18,4 +18,5 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV
...
@@ -18,4 +18,5 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
math.go
View file @
a3a23bc5
...
@@ -18,3 +18,40 @@ func RandInt64(min, max int64) int64 {
...
@@ -18,3 +18,40 @@ func RandInt64(min, max int64) int64 {
}
}
return
i
.
Int64
()
return
i
.
Int64
()
}
}
// pick Intersection from two array
func
Intersection
(
a
[]
string
,
b
[]
string
)
(
inter
[]
string
)
{
// interacting on the smallest list first can potentailly be faster...but not by much, worse case is the same
low
,
high
:=
a
,
b
if
len
(
a
)
>
len
(
b
)
{
low
=
b
high
=
a
}
done
:=
false
for
i
,
l
:=
range
low
{
for
j
,
h
:=
range
high
{
// get future index values
f1
:=
i
+
1
f2
:=
j
+
1
if
l
==
h
{
inter
=
append
(
inter
,
h
)
if
f1
<
len
(
low
)
&&
f2
<
len
(
high
)
{
// if the future values aren't the same then that's the end of the intersection
if
low
[
f1
]
!=
high
[
f2
]
{
done
=
true
}
}
// we don't want to interate on the entire list everytime, so remove the parts we already looped on will make it faster each pass
high
=
high
[
:
j
+
copy
(
high
[
j
:
],
high
[
j
+
1
:
])]
break
}
}
// nothing in the future so we are done
if
done
{
break
}
}
return
inter
}
math_test.go
View file @
a3a23bc5
...
@@ -18,3 +18,16 @@ func TestRandInt64(t *testing.T) {
...
@@ -18,3 +18,16 @@ func TestRandInt64(t *testing.T) {
t
.
Failed
()
t
.
Failed
()
}
}
}
}
func
TestIntersection
(
t
*
testing
.
T
)
{
a
:=
[]
string
{
"a"
,
"b"
}
b
:=
[]
string
{
"b"
,
"c"
}
c
:=
Intersection
(
a
,
b
)
if
c
[
0
]
==
"b"
{
t
.
Log
(
"success"
)
}
else
{
t
.
Failed
()
}
}
tools.go
View file @
a3a23bc5
...
@@ -6,8 +6,11 @@
...
@@ -6,8 +6,11 @@
package
utils
package
utils
import
(
import
(
"database/sql"
"errors"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
"io"
"io"
"reflect"
)
)
func
IOClose
(
fio
io
.
ReadCloser
)
{
func
IOClose
(
fio
io
.
ReadCloser
)
{
...
@@ -21,3 +24,181 @@ func IOClose(fio io.ReadCloser) {
...
@@ -21,3 +24,181 @@ func IOClose(fio io.ReadCloser) {
log
.
WithField
(
"error"
,
err
)
.
Error
(
"io.ReadCloser close error"
)
log
.
WithField
(
"error"
,
err
)
.
Error
(
"io.ReadCloser close error"
)
}
}
}
}
// Deep Copy
func
Copy
(
toValue
interface
{},
fromValue
interface
{})
(
err
error
)
{
var
(
isSlice
bool
amount
=
1
from
=
indirect
(
reflect
.
ValueOf
(
fromValue
))
to
=
indirect
(
reflect
.
ValueOf
(
toValue
))
)
if
!
to
.
CanAddr
()
{
return
errors
.
New
(
"copy to value is unaddressable"
)
}
// Return is from value is invalid
if
!
from
.
IsValid
()
{
return
}
// Just set it if possible to assign
if
from
.
Type
()
.
AssignableTo
(
to
.
Type
())
{
to
.
Set
(
from
)
return
}
fromType
:=
indirectType
(
from
.
Type
())
toType
:=
indirectType
(
to
.
Type
())
if
fromType
.
Kind
()
!=
reflect
.
Struct
||
toType
.
Kind
()
!=
reflect
.
Struct
{
return
}
if
to
.
Kind
()
==
reflect
.
Slice
{
isSlice
=
true
if
from
.
Kind
()
==
reflect
.
Slice
{
amount
=
from
.
Len
()
}
}
for
i
:=
0
;
i
<
amount
;
i
++
{
var
dest
,
source
reflect
.
Value
if
isSlice
{
// source
if
from
.
Kind
()
==
reflect
.
Slice
{
source
=
indirect
(
from
.
Index
(
i
))
}
else
{
source
=
indirect
(
from
)
}
// dest
dest
=
indirect
(
reflect
.
New
(
toType
)
.
Elem
())
}
else
{
source
=
indirect
(
from
)
dest
=
indirect
(
to
)
}
// Copy from field to field or method
for
_
,
field
:=
range
deepFields
(
fromType
)
{
name
:=
field
.
Name
if
fromField
:=
source
.
FieldByName
(
name
);
fromField
.
IsValid
()
{
// has field
if
toField
:=
dest
.
FieldByName
(
name
);
toField
.
IsValid
()
{
if
toField
.
CanSet
()
{
if
!
set
(
toField
,
fromField
)
{
if
err
:=
Copy
(
toField
.
Addr
()
.
Interface
(),
fromField
.
Interface
());
err
!=
nil
{
return
err
}
}
}
}
else
{
// try to set to method
var
toMethod
reflect
.
Value
if
dest
.
CanAddr
()
{
toMethod
=
dest
.
Addr
()
.
MethodByName
(
name
)
}
else
{
toMethod
=
dest
.
MethodByName
(
name
)
}
if
toMethod
.
IsValid
()
&&
toMethod
.
Type
()
.
NumIn
()
==
1
&&
fromField
.
Type
()
.
AssignableTo
(
toMethod
.
Type
()
.
In
(
0
))
{
toMethod
.
Call
([]
reflect
.
Value
{
fromField
})
}
}
}
}
// Copy from method to field
for
_
,
field
:=
range
deepFields
(
toType
)
{
name
:=
field
.
Name
var
fromMethod
reflect
.
Value
if
source
.
CanAddr
()
{
fromMethod
=
source
.
Addr
()
.
MethodByName
(
name
)
}
else
{
fromMethod
=
source
.
MethodByName
(
name
)
}
if
fromMethod
.
IsValid
()
&&
fromMethod
.
Type
()
.
NumIn
()
==
0
&&
fromMethod
.
Type
()
.
NumOut
()
==
1
{
if
toField
:=
dest
.
FieldByName
(
name
);
toField
.
IsValid
()
&&
toField
.
CanSet
()
{
values
:=
fromMethod
.
Call
([]
reflect
.
Value
{})
if
len
(
values
)
>=
1
{
set
(
toField
,
values
[
0
])
}
}
}
}
if
isSlice
{
if
dest
.
Addr
()
.
Type
()
.
AssignableTo
(
to
.
Type
()
.
Elem
())
{
to
.
Set
(
reflect
.
Append
(
to
,
dest
.
Addr
()))
}
else
if
dest
.
Type
()
.
AssignableTo
(
to
.
Type
()
.
Elem
())
{
to
.
Set
(
reflect
.
Append
(
to
,
dest
))
}
}
}
return
}
func
deepFields
(
reflectType
reflect
.
Type
)
[]
reflect
.
StructField
{
var
fields
[]
reflect
.
StructField
if
reflectType
=
indirectType
(
reflectType
);
reflectType
.
Kind
()
==
reflect
.
Struct
{
for
i
:=
0
;
i
<
reflectType
.
NumField
();
i
++
{
v
:=
reflectType
.
Field
(
i
)
if
v
.
Anonymous
{
fields
=
append
(
fields
,
deepFields
(
v
.
Type
)
...
)
}
else
{
fields
=
append
(
fields
,
v
)
}
}
}
return
fields
}
func
indirect
(
reflectValue
reflect
.
Value
)
reflect
.
Value
{
for
reflectValue
.
Kind
()
==
reflect
.
Ptr
{
reflectValue
=
reflectValue
.
Elem
()
}
return
reflectValue
}
func
indirectType
(
reflectType
reflect
.
Type
)
reflect
.
Type
{
for
reflectType
.
Kind
()
==
reflect
.
Ptr
||
reflectType
.
Kind
()
==
reflect
.
Slice
{
reflectType
=
reflectType
.
Elem
()
}
return
reflectType
}
func
set
(
to
,
from
reflect
.
Value
)
bool
{
if
from
.
IsValid
()
{
if
to
.
Kind
()
==
reflect
.
Ptr
{
// set `to` to nil if from is nil
if
from
.
Kind
()
==
reflect
.
Ptr
&&
from
.
IsNil
()
{
to
.
Set
(
reflect
.
Zero
(
to
.
Type
()))
return
true
}
else
if
to
.
IsNil
()
{
to
.
Set
(
reflect
.
New
(
to
.
Type
()
.
Elem
()))
}
to
=
to
.
Elem
()
}
if
from
.
Type
()
.
ConvertibleTo
(
to
.
Type
())
{
to
.
Set
(
from
.
Convert
(
to
.
Type
()))
}
else
if
scanner
,
ok
:=
to
.
Addr
()
.
Interface
()
.
(
sql
.
Scanner
);
ok
{
err
:=
scanner
.
Scan
(
from
.
Interface
())
if
err
!=
nil
{
return
false
}
}
else
if
from
.
Kind
()
==
reflect
.
Ptr
{
return
set
(
to
,
from
.
Elem
())
}
else
{
return
false
}
}
return
true
}
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