parent
d6aa01eb12
commit
cd0cd1c79d
@ -1,5 +1,5 @@
|
||||
package go_library
|
||||
|
||||
func Version() string {
|
||||
return "1.0.51"
|
||||
return "1.0.52"
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
package ast
|
||||
|
||||
type Reference int
|
||||
|
||||
const InvalidReference Reference = -1
|
||||
|
||||
func (r Reference) Valid() bool {
|
||||
return r != InvalidReference
|
||||
}
|
||||
|
||||
type Builder struct {
|
||||
tree Root
|
||||
lastIdx int
|
||||
}
|
||||
|
||||
func (b *Builder) Tree() *Root {
|
||||
return &b.tree
|
||||
}
|
||||
|
||||
func (b *Builder) NodeAt(ref Reference) *Node {
|
||||
return b.tree.at(ref)
|
||||
}
|
||||
|
||||
func (b *Builder) Reset() {
|
||||
b.tree.nodes = b.tree.nodes[:0]
|
||||
b.lastIdx = 0
|
||||
}
|
||||
|
||||
func (b *Builder) Push(n Node) Reference {
|
||||
b.lastIdx = len(b.tree.nodes)
|
||||
b.tree.nodes = append(b.tree.nodes, n)
|
||||
return Reference(b.lastIdx)
|
||||
}
|
||||
|
||||
func (b *Builder) PushAndChain(n Node) Reference {
|
||||
newIdx := len(b.tree.nodes)
|
||||
b.tree.nodes = append(b.tree.nodes, n)
|
||||
if b.lastIdx >= 0 {
|
||||
b.tree.nodes[b.lastIdx].next = newIdx - b.lastIdx
|
||||
}
|
||||
b.lastIdx = newIdx
|
||||
return Reference(b.lastIdx)
|
||||
}
|
||||
|
||||
func (b *Builder) AttachChild(parent Reference, child Reference) {
|
||||
b.tree.nodes[parent].child = int(child) - int(parent)
|
||||
}
|
||||
|
||||
func (b *Builder) Chain(from Reference, to Reference) {
|
||||
b.tree.nodes[from].next = int(to) - int(from)
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package characters
|
||||
|
||||
var invalidAsciiTable = [256]bool{
|
||||
0x00: true,
|
||||
0x01: true,
|
||||
0x02: true,
|
||||
0x03: true,
|
||||
0x04: true,
|
||||
0x05: true,
|
||||
0x06: true,
|
||||
0x07: true,
|
||||
0x08: true,
|
||||
// 0x09 TAB
|
||||
// 0x0A LF
|
||||
0x0B: true,
|
||||
0x0C: true,
|
||||
// 0x0D CR
|
||||
0x0E: true,
|
||||
0x0F: true,
|
||||
0x10: true,
|
||||
0x11: true,
|
||||
0x12: true,
|
||||
0x13: true,
|
||||
0x14: true,
|
||||
0x15: true,
|
||||
0x16: true,
|
||||
0x17: true,
|
||||
0x18: true,
|
||||
0x19: true,
|
||||
0x1A: true,
|
||||
0x1B: true,
|
||||
0x1C: true,
|
||||
0x1D: true,
|
||||
0x1E: true,
|
||||
0x1F: true,
|
||||
// 0x20 - 0x7E Printable ASCII characters
|
||||
0x7F: true,
|
||||
}
|
||||
|
||||
func InvalidAscii(b byte) bool {
|
||||
return invalidAsciiTable[b]
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package unstable
|
||||
|
||||
// root contains a full AST.
|
||||
//
|
||||
// It is immutable once constructed with Builder.
|
||||
type root struct {
|
||||
nodes []Node
|
||||
}
|
||||
|
||||
// Iterator over the top level nodes.
|
||||
func (r *root) Iterator() Iterator {
|
||||
it := Iterator{}
|
||||
if len(r.nodes) > 0 {
|
||||
it.node = &r.nodes[0]
|
||||
}
|
||||
return it
|
||||
}
|
||||
|
||||
func (r *root) at(idx reference) *Node {
|
||||
return &r.nodes[idx]
|
||||
}
|
||||
|
||||
type reference int
|
||||
|
||||
const invalidReference reference = -1
|
||||
|
||||
func (r reference) Valid() bool {
|
||||
return r != invalidReference
|
||||
}
|
||||
|
||||
type builder struct {
|
||||
tree root
|
||||
lastIdx int
|
||||
}
|
||||
|
||||
func (b *builder) Tree() *root {
|
||||
return &b.tree
|
||||
}
|
||||
|
||||
func (b *builder) NodeAt(ref reference) *Node {
|
||||
return b.tree.at(ref)
|
||||
}
|
||||
|
||||
func (b *builder) Reset() {
|
||||
b.tree.nodes = b.tree.nodes[:0]
|
||||
b.lastIdx = 0
|
||||
}
|
||||
|
||||
func (b *builder) Push(n Node) reference {
|
||||
b.lastIdx = len(b.tree.nodes)
|
||||
b.tree.nodes = append(b.tree.nodes, n)
|
||||
return reference(b.lastIdx)
|
||||
}
|
||||
|
||||
func (b *builder) PushAndChain(n Node) reference {
|
||||
newIdx := len(b.tree.nodes)
|
||||
b.tree.nodes = append(b.tree.nodes, n)
|
||||
if b.lastIdx >= 0 {
|
||||
b.tree.nodes[b.lastIdx].next = newIdx - b.lastIdx
|
||||
}
|
||||
b.lastIdx = newIdx
|
||||
return reference(b.lastIdx)
|
||||
}
|
||||
|
||||
func (b *builder) AttachChild(parent reference, child reference) {
|
||||
b.tree.nodes[parent].child = int(child) - int(parent)
|
||||
}
|
||||
|
||||
func (b *builder) Chain(from reference, to reference) {
|
||||
b.tree.nodes[from].next = int(to) - int(from)
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
// Package unstable provides APIs that do not meet the backward compatibility
|
||||
// guarantees yet.
|
||||
package unstable
|
@ -0,0 +1,121 @@
|
||||
package fnv1a
|
||||
|
||||
const (
|
||||
// FNV-1a
|
||||
offset64 = uint64(14695981039346656037)
|
||||
prime64 = uint64(1099511628211)
|
||||
|
||||
// Init64 is what 64 bits hash values should be initialized with.
|
||||
Init64 = offset64
|
||||
)
|
||||
|
||||
// HashString64 returns the hash of s.
|
||||
func HashString64(s string) uint64 {
|
||||
return AddString64(Init64, s)
|
||||
}
|
||||
|
||||
// HashBytes64 returns the hash of u.
|
||||
func HashBytes64(b []byte) uint64 {
|
||||
return AddBytes64(Init64, b)
|
||||
}
|
||||
|
||||
// HashUint64 returns the hash of u.
|
||||
func HashUint64(u uint64) uint64 {
|
||||
return AddUint64(Init64, u)
|
||||
}
|
||||
|
||||
// AddString64 adds the hash of s to the precomputed hash value h.
|
||||
func AddString64(h uint64, s string) uint64 {
|
||||
/*
|
||||
This is an unrolled version of this algorithm:
|
||||
|
||||
for _, c := range s {
|
||||
h = (h ^ uint64(c)) * prime64
|
||||
}
|
||||
|
||||
It seems to be ~1.5x faster than the simple loop in BenchmarkHash64:
|
||||
|
||||
- BenchmarkHash64/hash_function-4 30000000 56.1 ns/op 642.15 MB/s 0 B/op 0 allocs/op
|
||||
- BenchmarkHash64/hash_function-4 50000000 38.6 ns/op 932.35 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
*/
|
||||
for len(s) >= 8 {
|
||||
h = (h ^ uint64(s[0])) * prime64
|
||||
h = (h ^ uint64(s[1])) * prime64
|
||||
h = (h ^ uint64(s[2])) * prime64
|
||||
h = (h ^ uint64(s[3])) * prime64
|
||||
h = (h ^ uint64(s[4])) * prime64
|
||||
h = (h ^ uint64(s[5])) * prime64
|
||||
h = (h ^ uint64(s[6])) * prime64
|
||||
h = (h ^ uint64(s[7])) * prime64
|
||||
s = s[8:]
|
||||
}
|
||||
|
||||
if len(s) >= 4 {
|
||||
h = (h ^ uint64(s[0])) * prime64
|
||||
h = (h ^ uint64(s[1])) * prime64
|
||||
h = (h ^ uint64(s[2])) * prime64
|
||||
h = (h ^ uint64(s[3])) * prime64
|
||||
s = s[4:]
|
||||
}
|
||||
|
||||
if len(s) >= 2 {
|
||||
h = (h ^ uint64(s[0])) * prime64
|
||||
h = (h ^ uint64(s[1])) * prime64
|
||||
s = s[2:]
|
||||
}
|
||||
|
||||
if len(s) > 0 {
|
||||
h = (h ^ uint64(s[0])) * prime64
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// AddBytes64 adds the hash of b to the precomputed hash value h.
|
||||
func AddBytes64(h uint64, b []byte) uint64 {
|
||||
for len(b) >= 8 {
|
||||
h = (h ^ uint64(b[0])) * prime64
|
||||
h = (h ^ uint64(b[1])) * prime64
|
||||
h = (h ^ uint64(b[2])) * prime64
|
||||
h = (h ^ uint64(b[3])) * prime64
|
||||
h = (h ^ uint64(b[4])) * prime64
|
||||
h = (h ^ uint64(b[5])) * prime64
|
||||
h = (h ^ uint64(b[6])) * prime64
|
||||
h = (h ^ uint64(b[7])) * prime64
|
||||
b = b[8:]
|
||||
}
|
||||
|
||||
if len(b) >= 4 {
|
||||
h = (h ^ uint64(b[0])) * prime64
|
||||
h = (h ^ uint64(b[1])) * prime64
|
||||
h = (h ^ uint64(b[2])) * prime64
|
||||
h = (h ^ uint64(b[3])) * prime64
|
||||
b = b[4:]
|
||||
}
|
||||
|
||||
if len(b) >= 2 {
|
||||
h = (h ^ uint64(b[0])) * prime64
|
||||
h = (h ^ uint64(b[1])) * prime64
|
||||
b = b[2:]
|
||||
}
|
||||
|
||||
if len(b) > 0 {
|
||||
h = (h ^ uint64(b[0])) * prime64
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// AddUint64 adds the hash value of the 8 bytes of u to h.
|
||||
func AddUint64(h uint64, u uint64) uint64 {
|
||||
h = (h ^ ((u >> 56) & 0xFF)) * prime64
|
||||
h = (h ^ ((u >> 48) & 0xFF)) * prime64
|
||||
h = (h ^ ((u >> 40) & 0xFF)) * prime64
|
||||
h = (h ^ ((u >> 32) & 0xFF)) * prime64
|
||||
h = (h ^ ((u >> 24) & 0xFF)) * prime64
|
||||
h = (h ^ ((u >> 16) & 0xFF)) * prime64
|
||||
h = (h ^ ((u >> 8) & 0xFF)) * prime64
|
||||
h = (h ^ ((u >> 0) & 0xFF)) * prime64
|
||||
return h
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package fnv1a
|
||||
|
||||
const (
|
||||
// FNV-1a
|
||||
offset32 = uint32(2166136261)
|
||||
prime32 = uint32(16777619)
|
||||
|
||||
// Init32 is what 32 bits hash values should be initialized with.
|
||||
Init32 = offset32
|
||||
)
|
||||
|
||||
// HashString32 returns the hash of s.
|
||||
func HashString32(s string) uint32 {
|
||||
return AddString32(Init32, s)
|
||||
}
|
||||
|
||||
// HashBytes32 returns the hash of u.
|
||||
func HashBytes32(b []byte) uint32 {
|
||||
return AddBytes32(Init32, b)
|
||||
}
|
||||
|
||||
// HashUint32 returns the hash of u.
|
||||
func HashUint32(u uint32) uint32 {
|
||||
return AddUint32(Init32, u)
|
||||
}
|
||||
|
||||
// AddString32 adds the hash of s to the precomputed hash value h.
|
||||
func AddString32(h uint32, s string) uint32 {
|
||||
for len(s) >= 8 {
|
||||
h = (h ^ uint32(s[0])) * prime32
|
||||
h = (h ^ uint32(s[1])) * prime32
|
||||
h = (h ^ uint32(s[2])) * prime32
|
||||
h = (h ^ uint32(s[3])) * prime32
|
||||
h = (h ^ uint32(s[4])) * prime32
|
||||
h = (h ^ uint32(s[5])) * prime32
|
||||
h = (h ^ uint32(s[6])) * prime32
|
||||
h = (h ^ uint32(s[7])) * prime32
|
||||
s = s[8:]
|
||||
}
|
||||
|
||||
if len(s) >= 4 {
|
||||
h = (h ^ uint32(s[0])) * prime32
|
||||
h = (h ^ uint32(s[1])) * prime32
|
||||
h = (h ^ uint32(s[2])) * prime32
|
||||
h = (h ^ uint32(s[3])) * prime32
|
||||
s = s[4:]
|
||||
}
|
||||
|
||||
if len(s) >= 2 {
|
||||
h = (h ^ uint32(s[0])) * prime32
|
||||
h = (h ^ uint32(s[1])) * prime32
|
||||
s = s[2:]
|
||||
}
|
||||
|
||||
if len(s) > 0 {
|
||||
h = (h ^ uint32(s[0])) * prime32
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// AddBytes32 adds the hash of b to the precomputed hash value h.
|
||||
func AddBytes32(h uint32, b []byte) uint32 {
|
||||
for len(b) >= 8 {
|
||||
h = (h ^ uint32(b[0])) * prime32
|
||||
h = (h ^ uint32(b[1])) * prime32
|
||||
h = (h ^ uint32(b[2])) * prime32
|
||||
h = (h ^ uint32(b[3])) * prime32
|
||||
h = (h ^ uint32(b[4])) * prime32
|
||||
h = (h ^ uint32(b[5])) * prime32
|
||||
h = (h ^ uint32(b[6])) * prime32
|
||||
h = (h ^ uint32(b[7])) * prime32
|
||||
b = b[8:]
|
||||
}
|
||||
|
||||
if len(b) >= 4 {
|
||||
h = (h ^ uint32(b[0])) * prime32
|
||||
h = (h ^ uint32(b[1])) * prime32
|
||||
h = (h ^ uint32(b[2])) * prime32
|
||||
h = (h ^ uint32(b[3])) * prime32
|
||||
b = b[4:]
|
||||
}
|
||||
|
||||
if len(b) >= 2 {
|
||||
h = (h ^ uint32(b[0])) * prime32
|
||||
h = (h ^ uint32(b[1])) * prime32
|
||||
b = b[2:]
|
||||
}
|
||||
|
||||
if len(b) > 0 {
|
||||
h = (h ^ uint32(b[0])) * prime32
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// AddUint32 adds the hash value of the 8 bytes of u to h.
|
||||
func AddUint32(h, u uint32) uint32 {
|
||||
h = (h ^ ((u >> 24) & 0xFF)) * prime32
|
||||
h = (h ^ ((u >> 16) & 0xFF)) * prime32
|
||||
h = (h ^ ((u >> 8) & 0xFF)) * prime32
|
||||
h = (h ^ ((u >> 0) & 0xFF)) * prime32
|
||||
return h
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/segmentio/fasthash/fnv1a"
|
||||
)
|
||||
|
||||
const (
|
||||
hashTypeInt uint64 = 1 << iota
|
||||
hashTypeSignedInt
|
||||
hashTypeBool
|
||||
hashTypeString
|
||||
hashTypeHashable
|
||||
hashTypeNil
|
||||
)
|
||||
|
||||
type hasher struct {
|
||||
t uint64
|
||||
v interface{}
|
||||
}
|
||||
|
||||
func (h *hasher) Hash() uint64 {
|
||||
return NewHash(h.t, h.v)
|
||||
}
|
||||
|
||||
func NewHashable(t uint64, v interface{}) Hashable {
|
||||
return &hasher{t: t, v: v}
|
||||
}
|
||||
|
||||
func InitHash(t uint64) uint64 {
|
||||
return fnv1a.AddUint64(fnv1a.Init64, t)
|
||||
}
|
||||
|
||||
func NewHash(t uint64, in ...interface{}) uint64 {
|
||||
return AddToHash(InitHash(t), in...)
|
||||
}
|
||||
|
||||
func AddToHash(h uint64, in ...interface{}) uint64 {
|
||||
for i := range in {
|
||||
if in[i] == nil {
|
||||
continue
|
||||
}
|
||||
h = addToHash(h, in[i])
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func addToHash(h uint64, in interface{}) uint64 {
|
||||
switch v := in.(type) {
|
||||
case uint64:
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), v)
|
||||
case uint32:
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
case uint16:
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
case uint8:
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
case uint:
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
case int64:
|
||||
if v < 0 {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeSignedInt), uint64(-v))
|
||||
} else {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
}
|
||||
case int32:
|
||||
if v < 0 {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeSignedInt), uint64(-v))
|
||||
} else {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
}
|
||||
case int16:
|
||||
if v < 0 {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeSignedInt), uint64(-v))
|
||||
} else {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
}
|
||||
case int8:
|
||||
if v < 0 {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeSignedInt), uint64(-v))
|
||||
} else {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
}
|
||||
case int:
|
||||
if v < 0 {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeSignedInt), uint64(-v))
|
||||
} else {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeInt), uint64(v))
|
||||
}
|
||||
case bool:
|
||||
if v {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeBool), 1)
|
||||
} else {
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeBool), 2)
|
||||
}
|
||||
case string:
|
||||
return fnv1a.AddString64(fnv1a.AddUint64(h, hashTypeString), v)
|
||||
case Hashable:
|
||||
if in == nil {
|
||||
panic(fmt.Sprintf("could not hash nil element %T", in))
|
||||
}
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeHashable), v.Hash())
|
||||
case nil:
|
||||
return fnv1a.AddUint64(fnv1a.AddUint64(h, hashTypeNil), 0)
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported value type %T", in))
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
# hashstructure
|
||||
|
||||
hashstructure is a Go library for creating a unique hash value
|
||||
for arbitrary values in Go.
|
||||
|
||||
This can be used to key values in a hash (for use in a map, set, etc.)
|
||||
that are complex. The most common use case is comparing two values without
|
||||
sending data across the network, caching values locally (de-dup), and so on.
|
||||
|
||||
## Features
|
||||
|
||||
* Hash any arbitrary Go value, including complex types.
|
||||
|
||||
* Tag a struct field to ignore it and not affect the hash value.
|
||||
|
||||
* Tag a slice type struct field to treat it as a set where ordering
|
||||
doesn't affect the hash code but the field itself is still taken into
|
||||
account to create the hash value.
|
||||
|
||||
* Optionally specify a custom hash function to optimize for speed, collision
|
||||
avoidance for your data set, etc.
|
||||
|
||||
## Installation
|
||||
|
||||
Standard `go get`:
|
||||
|
||||
```
|
||||
$ go get github.com/mitchellh/hashstructure
|
||||
```
|
||||
|
||||
## Usage & Example
|
||||
|
||||
For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/hashstructure).
|
||||
|
||||
A quick code example is shown below:
|
||||
|
||||
|
||||
type ComplexStruct struct {
|
||||
Name string
|
||||
Age uint
|
||||
Metadata map[string]interface{}
|
||||
}
|
||||
|
||||
v := ComplexStruct{
|
||||
Name: "mitchellh",
|
||||
Age: 64,
|
||||
Metadata: map[string]interface{}{
|
||||
"car": true,
|
||||
"location": "California",
|
||||
"siblings": []string{"Bob", "John"},
|
||||
},
|
||||
}
|
||||
|
||||
hash, err := hashstructure.Hash(v, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%d", hash)
|
||||
// Output:
|
||||
// 2307517237273902113
|
@ -1,325 +0,0 @@
|
||||
package hashstructure
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// HashOptions are options that are available for hashing.
|
||||
type HashOptions struct {
|
||||
// Hasher is the hash function to use. If this isn't set, it will
|
||||
// default to FNV.
|
||||
Hasher hash.Hash64
|
||||
|
||||
// TagName is the struct tag to look at when hashing the structure.
|
||||
// By default this is "hash".
|
||||
TagName string
|
||||
}
|
||||
|
||||
// Hash returns the hash value of an arbitrary value.
|
||||
//
|
||||
// If opts is nil, then default options will be used. See HashOptions
|
||||
// for the default values.
|
||||
//
|
||||
// Notes on the value:
|
||||
//
|
||||
// * Unexported fields on structs are ignored and do not affect the
|
||||
// hash value.
|
||||
//
|
||||
// * Adding an exported field to a struct with the zero value will change
|
||||
// the hash value.
|
||||
//
|
||||
// For structs, the hashing can be controlled using tags. For example:
|
||||
//
|
||||
// struct {
|
||||
// Name string
|
||||
// UUID string `hash:"ignore"`
|
||||
// }
|
||||
//
|
||||
// The available tag values are:
|
||||
//
|
||||
// * "ignore" - The field will be ignored and not affect the hash code.
|
||||
//
|
||||
// * "set" - The field will be treated as a set, where ordering doesn't
|
||||
// affect the hash code. This only works for slices.
|
||||
//
|
||||
func Hash(v interface{}, opts *HashOptions) (uint64, error) {
|
||||
// Create default options
|
||||
if opts == nil {
|
||||
opts = &HashOptions{}
|
||||
}
|
||||
if opts.Hasher == nil {
|
||||
opts.Hasher = fnv.New64()
|
||||
}
|
||||
if opts.TagName == "" {
|
||||
opts.TagName = "hash"
|
||||
}
|
||||
|
||||
// Reset the hash
|
||||
opts.Hasher.Reset()
|
||||
|
||||
// Create our walker and walk the structure
|
||||
w := &walker{
|
||||
h: opts.Hasher,
|
||||
tag: opts.TagName,
|
||||
}
|
||||
return w.visit(reflect.ValueOf(v), nil)
|
||||
}
|
||||
|
||||
type walker struct {
|
||||
h hash.Hash64
|
||||
tag string
|
||||
}
|
||||
|
||||
type visitOpts struct {
|
||||
// Flags are a bitmask of flags to affect behavior of this visit
|
||||
Flags visitFlag
|
||||
|
||||
// Information about the struct containing this field
|
||||
Struct interface{}
|
||||
StructField string
|
||||
}
|
||||
|
||||
func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
|
||||
// Loop since these can be wrapped in multiple layers of pointers
|
||||
// and interfaces.
|
||||
for {
|
||||
// If we have an interface, dereference it. We have to do this up
|
||||
// here because it might be a nil in there and the check below must
|
||||
// catch that.
|
||||
if v.Kind() == reflect.Interface {
|
||||
v = v.Elem()
|
||||
continue
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = reflect.Indirect(v)
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// If it is nil, treat it like a zero.
|
||||
if !v.IsValid() {
|
||||
var tmp int8
|
||||
v = reflect.ValueOf(tmp)
|
||||
}
|
||||
|
||||
// Binary writing can use raw ints, we have to convert to
|
||||
// a sized-int, we'll choose the largest...
|
||||
switch v.Kind() {
|
||||
case reflect.Int:
|
||||
v = reflect.ValueOf(int64(v.Int()))
|
||||
case reflect.Uint:
|
||||
v = reflect.ValueOf(uint64(v.Uint()))
|
||||
case reflect.Bool:
|
||||
var tmp int8
|
||||
if v.Bool() {
|
||||
tmp = 1
|
||||
}
|
||||
v = reflect.ValueOf(tmp)
|
||||
}
|
||||
|
||||
k := v.Kind()
|
||||
|
||||
// We can shortcut numeric values by directly binary writing them
|
||||
if k >= reflect.Int && k <= reflect.Complex64 {
|
||||
// A direct hash calculation
|
||||
w.h.Reset()
|
||||
err := binary.Write(w.h, binary.LittleEndian, v.Interface())
|
||||
return w.h.Sum64(), err
|
||||
}
|
||||
|
||||
switch k {
|
||||
case reflect.Array:
|
||||
var h uint64
|
||||
l := v.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
current, err := w.visit(v.Index(i), nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
h = hashUpdateOrdered(w.h, h, current)
|
||||
}
|
||||
|
||||
return h, nil
|
||||
|
||||
case reflect.Map:
|
||||
var includeMap IncludableMap
|
||||
if opts != nil && opts.Struct != nil {
|
||||
if v, ok := opts.Struct.(IncludableMap); ok {
|
||||
includeMap = v
|
||||
}
|
||||
}
|
||||
|
||||
// Build the hash for the map. We do this by XOR-ing all the key
|
||||
// and value hashes. This makes it deterministic despite ordering.
|
||||
var h uint64
|
||||
for _, k := range v.MapKeys() {
|
||||
v := v.MapIndex(k)
|
||||
if includeMap != nil {
|
||||
incl, err := includeMap.HashIncludeMap(
|
||||
opts.StructField, k.Interface(), v.Interface())
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !incl {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
kh, err := w.visit(k, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
vh, err := w.visit(v, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
fieldHash := hashUpdateOrdered(w.h, kh, vh)
|
||||
h = hashUpdateUnordered(h, fieldHash)
|
||||
}
|
||||
|
||||
return h, nil
|
||||
|
||||
case reflect.Struct:
|
||||
var include Includable
|
||||
parent := v.Interface()
|
||||
if impl, ok := parent.(Includable); ok {
|
||||
include = impl
|
||||
}
|
||||
|
||||
t := v.Type()
|
||||
h, err := w.visit(reflect.ValueOf(t.Name()), nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
l := v.NumField()
|
||||
for i := 0; i < l; i++ {
|
||||
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
|
||||
var f visitFlag
|
||||
fieldType := t.Field(i)
|
||||
if fieldType.PkgPath != "" {
|
||||
// Unexported
|
||||
continue
|
||||
}
|
||||
|
||||
tag := fieldType.Tag.Get(w.tag)
|
||||
if tag == "ignore" {
|
||||
// Ignore this field
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if we implement includable and check it
|
||||
if include != nil {
|
||||
incl, err := include.HashInclude(fieldType.Name, v)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !incl {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
switch tag {
|
||||
case "set":
|
||||
f |= visitFlagSet
|
||||
}
|
||||
|
||||
kh, err := w.visit(reflect.ValueOf(fieldType.Name), nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
vh, err := w.visit(v, &visitOpts{
|
||||
Flags: f,
|
||||
Struct: parent,
|
||||
StructField: fieldType.Name,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
fieldHash := hashUpdateOrdered(w.h, kh, vh)
|
||||
h = hashUpdateUnordered(h, fieldHash)
|
||||
}
|
||||
}
|
||||
|
||||
return h, nil
|
||||
|
||||
case reflect.Slice:
|
||||
// We have two behaviors here. If it isn't a set, then we just
|
||||
// visit all the elements. If it is a set, then we do a deterministic
|
||||
// hash code.
|
||||
var h uint64
|
||||
var set bool
|
||||
if opts != nil {
|
||||
set = (opts.Flags & visitFlagSet) != 0
|
||||
}
|
||||
l := v.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
current, err := w.visit(v.Index(i), nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if set {
|
||||
h = hashUpdateUnordered(h, current)
|
||||
} else {
|
||||
h = hashUpdateOrdered(w.h, h, current)
|
||||
}
|
||||
}
|
||||
|
||||
return h, nil
|
||||
|
||||
case reflect.String:
|
||||
// Directly hash
|
||||
w.h.Reset()
|
||||
_, err := w.h.Write([]byte(v.String()))
|
||||
return w.h.Sum64(), err
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("unknown kind to hash: %s", k)
|
||||
}
|
||||
}
|
||||
|
||||
func hashUpdateOrdered(h hash.Hash64, a, b uint64) uint64 {
|
||||
// For ordered updates, use a real hash function
|
||||
h.Reset()
|
||||
|
||||
// We just panic if the binary writes fail because we are writing
|
||||
// an int64 which should never be fail-able.
|
||||
e1 := binary.Write(h, binary.LittleEndian, a)
|
||||
e2 := binary.Write(h, binary.LittleEndian, b)
|
||||
if e1 != nil {
|
||||
panic(e1)
|
||||
}
|
||||
if e2 != nil {
|
||||
panic(e2)
|
||||
}
|
||||
|
||||
return h.Sum64()
|
||||
}
|
||||
|
||||
func hashUpdateUnordered(a, b uint64) uint64 {
|
||||
return a ^ b
|
||||
}
|
||||
|
||||
// visitFlag is used as a bitmask for affecting visit behavior
|
||||
type visitFlag uint
|
||||
|
||||
const (
|
||||
visitFlagInvalid visitFlag = iota
|
||||
visitFlagSet = iota << 1
|
||||
)
|
||||
|
||||
var (
|
||||
_ = visitFlagInvalid
|
||||
)
|
@ -1,15 +0,0 @@
|
||||
package hashstructure
|
||||
|
||||
// Includable is an interface that can optionally be implemented by
|
||||
// a struct. It will be called for each field in the struct to check whether
|
||||
// it should be included in the hash.
|
||||
type Includable interface {
|
||||
HashInclude(field string, v interface{}) (bool, error)
|
||||
}
|
||||
|
||||
// IncludableMap is an interface that can optionally be implemented by
|
||||
// a struct. It will be called when a map-type field is found to ask the
|
||||
// struct if the map item should be included in the hash.
|
||||
type IncludableMap interface {
|
||||
HashIncludeMap(field string, k, v interface{}) (bool, error)
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package exql
|
||||
|
||||
const (
|
||||
errExpectingHashableFmt = "expecting hashable value, got %T"
|
||||
)
|
@ -1,26 +0,0 @@
|
||||
package exql
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/upper/db/v4/internal/cache"
|
||||
)
|
||||
|
||||
type hash struct {
|
||||
v atomic.Value
|
||||
}
|
||||
|
||||
func (h *hash) Hash(i interface{}) string {
|
||||
v := h.v.Load()
|
||||
if r, ok := v.(string); ok && r != "" {
|
||||
return r
|
||||
}
|
||||
s := reflect.TypeOf(i).String() + ":" + cache.Hash(i)
|
||||
h.v.Store(s)
|
||||
return s
|
||||
}
|
||||
|
||||
func (h *hash) Reset() {
|
||||
h.v.Store("")
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package exql
|
||||
|
||||
const (
|
||||
FragmentType_None uint64 = iota + 713910251627
|
||||
|
||||
FragmentType_And
|
||||
FragmentType_Column
|
||||
FragmentType_ColumnValue
|
||||
FragmentType_ColumnValues
|
||||
FragmentType_Columns
|
||||
FragmentType_Database
|
||||
FragmentType_GroupBy
|
||||
FragmentType_Join
|
||||
FragmentType_Joins
|
||||
FragmentType_Nil
|
||||
FragmentType_Or
|
||||
FragmentType_Limit
|
||||
FragmentType_Offset
|
||||
FragmentType_OrderBy
|
||||
FragmentType_Order
|
||||
FragmentType_Raw
|
||||
FragmentType_Returning
|
||||
FragmentType_SortBy
|
||||
FragmentType_SortColumn
|
||||
FragmentType_SortColumns
|
||||
FragmentType_Statement
|
||||
FragmentType_StatementType
|
||||
FragmentType_Table
|
||||
FragmentType_Value
|
||||
FragmentType_On
|
||||
FragmentType_Using
|
||||
FragmentType_ValueGroups
|
||||
FragmentType_Values
|
||||
FragmentType_Where
|
||||
)
|
@ -0,0 +1,8 @@
|
||||
package sqladapter
|
||||
|
||||
const (
|
||||
hashTypeNone = iota + 345065139389
|
||||
|
||||
hashTypeCollection
|
||||
hashTypePrimaryKeys
|
||||
)
|
@ -0,0 +1,188 @@
|
||||
// go generate gen.go
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
package hpack
|
||||
|
||||
var staticTable = &headerFieldTable{
|
||||
evictCount: 0,
|
||||
byName: map[string]uint64{
|
||||
":authority": 1,
|
||||
":method": 3,
|
||||
":path": 5,
|
||||
":scheme": 7,
|
||||
":status": 14,
|
||||
"accept-charset": 15,
|
||||
"accept-encoding": 16,
|
||||
"accept-language": 17,
|
||||
"accept-ranges": 18,
|
||||
"accept": 19,
|
||||
"access-control-allow-origin": 20,
|
||||
"age": 21,
|
||||
"allow": 22,
|
||||
"authorization": 23,
|
||||
"cache-control": 24,
|
||||
"content-disposition": 25,
|
||||
"content-encoding": 26,
|
||||
"content-language": 27,
|
||||
"content-length": 28,
|
||||
"content-location": 29,
|
||||
"content-range": 30,
|
||||
"content-type": 31,
|
||||
"cookie": 32,
|
||||
"date": 33,
|
||||
"etag": 34,
|
||||
"expect": 35,
|
||||
"expires": 36,
|
||||
"from": 37,
|
||||
"host": 38,
|
||||
"if-match": 39,
|
||||
"if-modified-since": 40,
|
||||
"if-none-match": 41,
|
||||
"if-range": 42,
|
||||
"if-unmodified-since": 43,
|
||||
"last-modified": 44,
|
||||
"link": 45,
|
||||
"location": 46,
|
||||
"max-forwards": 47,
|
||||
"proxy-authenticate": 48,
|
||||
"proxy-authorization": 49,
|
||||
"range": 50,
|
||||
"referer": 51,
|
||||
"refresh": 52,
|
||||
"retry-after": 53,
|
||||
"server": 54,
|
||||
"set-cookie": 55,
|
||||
"strict-transport-security": 56,
|
||||
"transfer-encoding": 57,
|
||||
"user-agent": 58,
|
||||
"vary": 59,
|
||||
"via": 60,
|
||||
"www-authenticate": 61,
|
||||
},
|
||||
byNameValue: map[pairNameValue]uint64{
|
||||
{name: ":authority", value: ""}: 1,
|
||||
{name: ":method", value: "GET"}: 2,
|
||||
{name: ":method", value: "POST"}: 3,
|
||||
{name: ":path", value: "/"}: 4,
|
||||
{name: ":path", value: "/index.html"}: 5,
|
||||
{name: ":scheme", value: "http"}: 6,
|
||||
{name: ":scheme", value: "https"}: 7,
|
||||
{name: ":status", value: "200"}: 8,
|
||||
{name: ":status", value: "204"}: 9,
|
||||
{name: ":status", value: "206"}: 10,
|
||||
{name: ":status", value: "304"}: 11,
|
||||
{name: ":status", value: "400"}: 12,
|
||||
{name: ":status", value: "404"}: 13,
|
||||
{name: ":status", value: "500"}: 14,
|
||||
{name: "accept-charset", value: ""}: 15,
|
||||
{name: "accept-encoding", value: "gzip, deflate"}: 16,
|
||||
{name: "accept-language", value: ""}: 17,
|
||||
{name: "accept-ranges", value: ""}: 18,
|
||||
{name: "accept", value: ""}: 19,
|
||||
{name: "access-control-allow-origin", value: ""}: 20,
|
||||
{name: "age", value: ""}: 21,
|
||||
{name: "allow", value: ""}: 22,
|
||||
{name: "authorization", value: ""}: 23,
|
||||
{name: "cache-control", value: ""}: 24,
|
||||
{name: "content-disposition", value: ""}: 25,
|
||||
{name: "content-encoding", value: ""}: 26,
|
||||
{name: "content-language", value: ""}: 27,
|
||||
{name: "content-length", value: ""}: 28,
|
||||
{name: "content-location", value: ""}: 29,
|
||||
{name: "content-range", value: ""}: 30,
|
||||
{name: "content-type", value: ""}: 31,
|
||||
{name: "cookie", value: ""}: 32,
|
||||
{name: "date", value: ""}: 33,
|
||||
{name: "etag", value: ""}: 34,
|
||||
{name: "expect", value: ""}: 35,
|
||||
{name: "expires", value: ""}: 36,
|
||||
{name: "from", value: ""}: 37,
|
||||
{name: "host", value: ""}: 38,
|
||||
{name: "if-match", value: ""}: 39,
|
||||
{name: "if-modified-since", value: ""}: 40,
|
||||
{name: "if-none-match", value: ""}: 41,
|
||||
{name: "if-range", value: ""}: 42,
|
||||
{name: "if-unmodified-since", value: ""}: 43,
|
||||
{name: "last-modified", value: ""}: 44,
|
||||
{name: "link", value: ""}: 45,
|
||||
{name: "location", value: ""}: 46,
|
||||
{name: "max-forwards", value: ""}: 47,
|
||||
{name: "proxy-authenticate", value: ""}: 48,
|
||||
{name: "proxy-authorization", value: ""}: 49,
|
||||
{name: "range", value: ""}: 50,
|
||||
{name: "referer", value: ""}: 51,
|
||||
{name: "refresh", value: ""}: 52,
|
||||
{name: "retry-after", value: ""}: 53,
|
||||
{name: "server", value: ""}: 54,
|
||||
{name: "set-cookie", value: ""}: 55,
|
||||
{name: "strict-transport-security", value: ""}: 56,
|
||||
{name: "transfer-encoding", value: ""}: 57,
|
||||
{name: "user-agent", value: ""}: 58,
|
||||
{name: "vary", value: ""}: 59,
|
||||
{name: "via", value: ""}: 60,
|
||||
{name: "www-authenticate", value: ""}: 61,
|
||||
},
|
||||
ents: []HeaderField{
|
||||
{Name: ":authority", Value: "", Sensitive: false},
|
||||
{Name: ":method", Value: "GET", Sensitive: false},
|
||||
{Name: ":method", Value: "POST", Sensitive: false},
|
||||
{Name: ":path", Value: "/", Sensitive: false},
|
||||
{Name: ":path", Value: "/index.html", Sensitive: false},
|
||||
{Name: ":scheme", Value: "http", Sensitive: false},
|
||||
{Name: ":scheme", Value: "https", Sensitive: false},
|
||||
{Name: ":status", Value: "200", Sensitive: false},
|
||||
{Name: ":status", Value: "204", Sensitive: false},
|
||||
{Name: ":status", Value: "206", Sensitive: false},
|
||||
{Name: ":status", Value: "304", Sensitive: false},
|
||||
{Name: ":status", Value: "400", Sensitive: false},
|
||||
{Name: ":status", Value: "404", Sensitive: false},
|
||||
{Name: ":status", Value: "500", Sensitive: false},
|
||||
{Name: "accept-charset", Value: "", Sensitive: false},
|
||||
{Name: "accept-encoding", Value: "gzip, deflate", Sensitive: false},
|
||||
{Name: "accept-language", Value: "", Sensitive: false},
|
||||
{Name: "accept-ranges", Value: "", Sensitive: false},
|
||||
{Name: "accept", Value: "", Sensitive: false},
|
||||
{Name: "access-control-allow-origin", Value: "", Sensitive: false},
|
||||
{Name: "age", Value: "", Sensitive: false},
|
||||
{Name: "allow", Value: "", Sensitive: false},
|
||||
{Name: "authorization", Value: "", Sensitive: false},
|
||||
{Name: "cache-control", Value: "", Sensitive: false},
|
||||
{Name: "content-disposition", Value: "", Sensitive: false},
|
||||
{Name: "content-encoding", Value: "", Sensitive: false},
|
||||
{Name: "content-language", Value: "", Sensitive: false},
|
||||
{Name: "content-length", Value: "", Sensitive: false},
|
||||
{Name: "content-location", Value: "", Sensitive: false},
|
||||
{Name: "content-range", Value: "", Sensitive: false},
|
||||
{Name: "content-type", Value: "", Sensitive: false},
|
||||
{Name: "cookie", Value: "", Sensitive: false},
|
||||
{Name: "date", Value: "", Sensitive: false},
|
||||
{Name: "etag", Value: "", Sensitive: false},
|
||||
{Name: "expect", Value: "", Sensitive: false},
|
||||
{Name: "expires", Value: "", Sensitive: false},
|
||||
{Name: "from", Value: "", Sensitive: false},
|
||||
{Name: "host", Value: "", Sensitive: false},
|
||||
{Name: "if-match", Value: "", Sensitive: false},
|
||||
{Name: "if-modified-since", Value: "", Sensitive: false},
|
||||
{Name: "if-none-match", Value: "", Sensitive: false},
|
||||
{Name: "if-range", Value: "", Sensitive: false},
|
||||
{Name: "if-unmodified-since", Value: "", Sensitive: false},
|
||||
{Name: "last-modified", Value: "", Sensitive: false},
|
||||
{Name: "link", Value: "", Sensitive: false},
|
||||
{Name: "location", Value: "", Sensitive: false},
|
||||
{Name: "max-forwards", Value: "", Sensitive: false},
|
||||
{Name: "proxy-authenticate", Value: "", Sensitive: false},
|
||||
{Name: "proxy-authorization", Value: "", Sensitive: false},
|
||||
{Name: "range", Value: "", Sensitive: false},
|
||||
{Name: "referer", Value: "", Sensitive: false},
|
||||
{Name: "refresh", Value: "", Sensitive: false},
|
||||
{Name: "retry-after", Value: "", Sensitive: false},
|
||||
{Name: "server", Value: "", Sensitive: false},
|
||||
{Name: "set-cookie", Value: "", Sensitive: false},
|
||||
{Name: "strict-transport-security", Value: "", Sensitive: false},
|
||||
{Name: "transfer-encoding", Value: "", Sensitive: false},
|
||||
{Name: "user-agent", Value: "", Sensitive: false},
|
||||
{Name: "vary", Value: "", Sensitive: false},
|
||||
{Name: "via", Value: "", Sensitive: false},
|
||||
{Name: "www-authenticate", Value: "", Sensitive: false},
|
||||
},
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Minimal copy of functionality from x/sys/unix so the cpu package can call
|
||||
// sysctl without depending on x/sys/unix.
|
||||
|
||||
const (
|
||||
// From OpenBSD's sys/sysctl.h.
|
||||
_CTL_MACHDEP = 7
|
||||
|
||||
// From OpenBSD's machine/cpu.h.
|
||||
_CPU_ID_AA64ISAR0 = 2
|
||||
_CPU_ID_AA64ISAR1 = 3
|
||||
)
|
||||
|
||||
// Implemented in the runtime package (runtime/sys_openbsd3.go)
|
||||
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
//go:linkname syscall_syscall6 syscall.syscall6
|
||||
|
||||
func sysctl(mib []uint32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
|
||||
_, _, errno := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var libc_sysctl_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
|
||||
|
||||
func sysctlUint64(mib []uint32) (uint64, bool) {
|
||||
var out uint64
|
||||
nout := unsafe.Sizeof(out)
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return out, true
|
||||
}
|
||||
|
||||
func doinit() {
|
||||
setMinimalFeatures()
|
||||
|
||||
// Get ID_AA64ISAR0 and ID_AA64ISAR1 from sysctl.
|
||||
isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
isar1, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR1})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
parseARM64SystemRegisters(isar0, isar1, 0)
|
||||
|
||||
Initialized = true
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sysctl(SB)
|
||||
|
||||
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
|
@ -0,0 +1,15 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !aix && !linux && (ppc64 || ppc64le)
|
||||
// +build !aix
|
||||
// +build !linux
|
||||
// +build ppc64 ppc64le
|
||||
|
||||
package cpu
|
||||
|
||||
func archInit() {
|
||||
PPC64.IsPOWER8 = true
|
||||
Initialized = true
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ppc64, BSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
|
||||
if val < 0 {
|
||||
return "-" + uitoa(uint(-val))
|
||||
}
|
||||
return uitoa(uint(val))
|
||||
}
|
||||
|
||||
func uitoa(val uint) string {
|
||||
var buf [32]byte // big enough for int64
|
||||
i := len(buf) - 1
|
||||
for val >= 10 {
|
||||
buf[i] = byte(val%10 + '0')
|
||||
i--
|
||||
val /= 10
|
||||
}
|
||||
buf[i] = byte(val + '0')
|
||||
return string(buf[i:])
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build darwin && go1.12 && !go1.13
|
||||
// +build darwin,go1.12,!go1.13
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const _SYS_GETDIRENTRIES64 = 344
|
||||
|
||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
// To implement this using libSystem we'd need syscall_syscallPtr for
|
||||
// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
|
||||
// back to raw syscalls for this func on Go 1.12.
|
||||
var p unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
p = unsafe.Pointer(&buf[0])
|
||||
} else {
|
||||
p = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
return n, errnoErr(e1)
|
||||
}
|
||||
return n, nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue