Update comments across the codebase

This commit is contained in:
Harshavardhana 2015-03-03 02:36:12 -08:00
parent 137584d658
commit 3a3c8645fc
24 changed files with 198 additions and 346 deletions

2
.gitignore vendored
View File

@ -5,4 +5,4 @@ cover.out
minio minio
**/*.test **/*.test
**/*.sublime-workspace **/*.sublime-workspace
deadcode verifier

View File

@ -7,16 +7,17 @@ checkdeps:
@(env bash $(PWD)/buildscripts/checkdeps.sh) @(env bash $(PWD)/buildscripts/checkdeps.sh)
checkgopath: checkgopath:
@echo "Checking project in ${MINIOPATH}" @echo "Checking if project is at ${MINIOPATH}"
@if [ ! -d ${MINIOPATH} ]; then echo "Project not found in $GOPATH, please follow instructions provided at https://github.com/Minio-io/minio/blob/master/CONTRIBUTING.md#setup-your-minio-github-repository" && exit 1; fi @if [ ! -d ${MINIOPATH} ]; then echo "Project not found in $GOPATH, please follow instructions provided at https://github.com/Minio-io/minio/blob/master/CONTRIBUTING.md#setup-your-minio-github-repository" && exit 1; fi
getdeps: checkdeps checkgopath getdeps: checkdeps checkgopath
@go get github.com/tools/godep && echo "Installed godep" @go get github.com/tools/godep && echo "Installed godep"
deadcode: getdeps verifier: getdeps
@go run buildscripts/deadcode.go . @echo "Checking for offending code"
@go run buildscripts/verifier.go ${PWD}
build-all: getdeps deadcode build-all: verifier
@echo "Building Libraries" @echo "Building Libraries"
@godep go generate ./... @godep go generate ./...
@godep go build ./... @godep go build ./...

View File

@ -24,46 +24,91 @@ func appendUniq(slice []string, i string) []string {
return append(slice, i) return append(slice, i)
} }
func getAllFiles(path string, fl os.FileInfo, err error) error { // error formats the error to standard error, adding program
// identification and a newline
func errorf(format string, args ...interface{}) {
fmt.Fprintf(os.Stderr, "verifier: "+format+"\n", args...)
exitCode = 2
}
type Package struct {
p *ast.Package
fs *token.FileSet
decl map[string]ast.Node
missingcomments map[string]ast.Node
used map[string]bool
}
type usedWalker Package
// Walks through the AST marking used identifiers.
func (p *usedWalker) Visit(node ast.Node) ast.Visitor {
// just be stupid and mark all *ast.Ident
switch n := node.(type) {
case *ast.Ident:
p.used[n.Name] = true
}
return p
}
type Report struct {
pos token.Pos
name string
}
type Reports []Report
// Len
func (l Reports) Len() int { return len(l) }
// Less
func (l Reports) Less(i, j int) bool { return l[i].pos < l[j].pos }
// Swap
func (l Reports) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
// Visits files for used nodes.
func (p *Package) Visit(node ast.Node) ast.Visitor {
u := usedWalker(*p) // hopefully p fields are references.
switch n := node.(type) {
// don't walk whole file, but only:
case *ast.ValueSpec:
// - variable initializers
for _, value := range n.Values {
ast.Walk(&u, value)
}
// variable types.
if n.Type != nil {
ast.Walk(&u, n.Type)
}
case *ast.BlockStmt:
// - function bodies
for _, stmt := range n.List {
ast.Walk(&u, stmt)
}
case *ast.FuncDecl:
// - function signatures
ast.Walk(&u, n.Type)
case *ast.TypeSpec:
// - type declarations
ast.Walk(&u, n.Type)
}
return p
}
func getAllMinioPkgs(path string, fl os.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
} }
if fl.IsDir() { if fl.IsDir() {
// Skip godeps
if strings.Contains(path, "Godeps") {
return nil
}
dirs = appendUniq(dirs, path) dirs = appendUniq(dirs, path)
} }
return nil return nil
} }
func main() {
flag.Parse()
if flag.NArg() == 0 {
doDir(".")
} else {
for _, name := range flag.Args() {
// Is it a directory?
if fi, err := os.Stat(name); err == nil && fi.IsDir() {
err := filepath.Walk(name, getAllFiles)
if err != nil {
errorf(err.Error())
}
for _, dir := range dirs {
doDir(dir)
}
} else {
errorf("not a directory: %s", name)
}
}
}
os.Exit(exitCode)
}
// error formats the error to standard error, adding program
// identification and a newline
func errorf(format string, args ...interface{}) {
fmt.Fprintf(os.Stderr, "deadcode: "+format+"\n", args...)
exitCode = 2
}
func doDir(name string) { func doDir(name string) {
notests := func(info os.FileInfo) bool { notests := func(info os.FileInfo) bool {
if !info.IsDir() && strings.HasSuffix(info.Name(), ".go") && if !info.IsDir() && strings.HasSuffix(info.Name(), ".go") &&
@ -83,14 +128,6 @@ func doDir(name string) {
} }
} }
type Package struct {
p *ast.Package
fs *token.FileSet
decl map[string]ast.Node
missingcomments map[string]ast.Node
used map[string]bool
}
func doPackage(fs *token.FileSet, pkg *ast.Package) { func doPackage(fs *token.FileSet, pkg *ast.Package) {
p := &Package{ p := &Package{
p: pkg, p: pkg,
@ -179,53 +216,25 @@ func doPackage(fs *token.FileSet, pkg *ast.Package) {
} }
} }
type Report struct { func main() {
pos token.Pos flag.Parse()
name string if flag.NArg() == 0 {
} doDir(".")
type Reports []Report } else {
for _, name := range flag.Args() {
func (l Reports) Len() int { return len(l) } // Is it a directory?
func (l Reports) Less(i, j int) bool { return l[i].pos < l[j].pos } if fi, err := os.Stat(name); err == nil && fi.IsDir() {
func (l Reports) Swap(i, j int) { l[i], l[j] = l[j], l[i] } err := filepath.Walk(name, getAllMinioPkgs)
if err != nil {
// Visits files for used nodes. errorf(err.Error())
func (p *Package) Visit(node ast.Node) ast.Visitor { }
u := usedWalker(*p) // hopefully p fields are references. for _, dir := range dirs {
switch n := node.(type) { doDir(dir)
// don't walk whole file, but only: }
case *ast.ValueSpec: } else {
// - variable initializers errorf("not a directory: %s", name)
for _, value := range n.Values { }
ast.Walk(&u, value)
} }
// variable types.
if n.Type != nil {
ast.Walk(&u, n.Type)
}
case *ast.BlockStmt:
// - function bodies
for _, stmt := range n.List {
ast.Walk(&u, stmt)
}
case *ast.FuncDecl:
// - function signatures
ast.Walk(&u, n.Type)
case *ast.TypeSpec:
// - type declarations
ast.Walk(&u, n.Type)
} }
return p os.Exit(exitCode)
}
type usedWalker Package
// Walks through the AST marking used identifiers.
func (p *usedWalker) Visit(node ast.Node) ast.Visitor {
// just be stupid and mark all *ast.Ident
switch n := node.(type) {
case *ast.Ident:
p.used[n.Name] = true
}
return p
} }

View File

@ -52,6 +52,7 @@ func validateHandler(conf config.Config, h http.Handler) http.Handler {
return vHandler{conf, h} return vHandler{conf, h}
} }
// Validate handler ServeHTTP() wrapper
func (h vHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h vHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
accessKey := stripAccessKey(r) accessKey := stripAccessKey(r)
acceptsContentType := getContentType(r) acceptsContentType := getContentType(r)
@ -95,6 +96,7 @@ func ignoreResourcesHandler(h http.Handler) http.Handler {
return rHandler{h} return rHandler{h}
} }
// Resource handler ServeHTTP() wrapper
func (h rHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h rHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
acceptsContentType := getContentType(r) acceptsContentType := getContentType(r)
if ignoreUnImplementedObjectResources(r) || ignoreUnImplementedBucketResources(r) { if ignoreUnImplementedObjectResources(r) || ignoreUnImplementedBucketResources(r) {
@ -109,7 +111,7 @@ func (h rHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//// helpers //// helpers
// Checks requests for unimplemented resources // Checks requests for unimplemented Bucket resources
func ignoreUnImplementedBucketResources(req *http.Request) bool { func ignoreUnImplementedBucketResources(req *http.Request) bool {
q := req.URL.Query() q := req.URL.Query()
for name := range q { for name := range q {
@ -120,6 +122,7 @@ func ignoreUnImplementedBucketResources(req *http.Request) bool {
return false return false
} }
// Checks requests for unimplemented Object resources
func ignoreUnImplementedObjectResources(req *http.Request) bool { func ignoreUnImplementedObjectResources(req *http.Request) bool {
q := req.URL.Query() q := req.URL.Query()
for name := range q { for name := range q {

View File

@ -56,8 +56,13 @@ func generateBucketsListResult(buckets []mstorage.BucketMetadata) BucketListResp
type ItemKey []*Item type ItemKey []*Item
func (b ItemKey) Len() int { return len(b) } // Len
func (b ItemKey) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b ItemKey) Len() int { return len(b) }
// Swap
func (b ItemKey) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
// Less
func (b ItemKey) Less(i, j int) bool { return b[i].Key < b[j].Key } func (b ItemKey) Less(i, j int) bool { return b[i].Key < b[j].Key }
// takes a set of objects and prepares the objects for serialization // takes a set of objects and prepares the objects for serialization

View File

@ -42,6 +42,7 @@ type encoder interface {
Encode(v interface{}) error Encode(v interface{}) error
} }
// Http wrapper handler
func HttpHandler() http.Handler { func HttpHandler() http.Handler {
mux := mux.NewRouter() mux := mux.NewRouter()
var api = webUiApi{} var api = webUiApi{}

View File

@ -32,6 +32,7 @@ type HttpServerConfig struct {
type HttpServer struct{} type HttpServer struct{}
// Start http server
func Start(handler http.Handler, config HttpServerConfig) (chan<- string, <-chan error, *HttpServer) { func Start(handler http.Handler, config HttpServerConfig) (chan<- string, <-chan error, *HttpServer) {
ctrlChannel := make(chan string) ctrlChannel := make(chan string)
errorChannel := make(chan error) errorChannel := make(chan error)

View File

@ -143,6 +143,7 @@ func getStorageChannels(storageType StorageType) (ctrlChans []chan<- string, sta
return return
} }
// Create channels
func Start(configs []ServerConfig) { func Start(configs []ServerConfig) {
// reflected looping is necessary to remove dead channels from loop and not flood switch // reflected looping is necessary to remove dead channels from loop and not flood switch
ctrlChans, statusChans := getHttpChannels(configs) ctrlChans, statusChans := getHttpChannels(configs)

View File

@ -47,6 +47,7 @@ type EncoderParams struct {
Technique EncoderTechnique Technique EncoderTechnique
} }
// populate new header
func NewHeader(key string, part uint8, metadata Metadata, encoderParams EncoderParams) DataHeader { func NewHeader(key string, part uint8, metadata Metadata, encoderParams EncoderParams) DataHeader {
header := DataHeader{} header := DataHeader{}
header.Key = key header.Key = key
@ -61,6 +62,7 @@ func NewHeader(key string, part uint8, metadata Metadata, encoderParams EncoderP
return header return header
} }
// validate populated header
func ValidateHeader(header DataHeader) bool { func ValidateHeader(header DataHeader) bool {
if header.Key == "" || header.Part < 0 || len(header.Metadata) < 2 { if header.Key == "" || header.Part < 0 || len(header.Metadata) < 2 {
return false return false
@ -73,6 +75,7 @@ func ValidateHeader(header DataHeader) bool {
return true return true
} }
// Write data, returns error upon any failure
func WriteData(target io.Writer, header DataHeader, data io.Reader) error { func WriteData(target io.Writer, header DataHeader, data io.Reader) error {
if !ValidateHeader(header) { if !ValidateHeader(header) {
return fmt.Errorf("Invalid header") return fmt.Errorf("Invalid header")

View File

@ -73,6 +73,7 @@ type DonutFrameFooter struct {
type Data bytes.Buffer type Data bytes.Buffer
// Write Donut format to input io.Writer, returns error upon any failure
func WriteFrame(target io.Writer, reader io.Reader, length uint64) error { func WriteFrame(target io.Writer, reader io.Reader, length uint64) error {
// write header // write header
header := DonutFrameHeader{ header := DonutFrameHeader{

View File

@ -29,7 +29,6 @@ import (
"sync" "sync"
mstorage "github.com/minio-io/minio/pkg/storage" mstorage "github.com/minio-io/minio/pkg/storage"
"github.com/minio-io/minio/pkg/utils/helpers"
"github.com/minio-io/minio/pkg/utils/policy" "github.com/minio-io/minio/pkg/utils/policy"
) )
@ -42,6 +41,7 @@ type SerializedMetadata struct {
ContentType string ContentType string
} }
// Start filesystem channel
func Start(root string) (chan<- string, <-chan error, *storage) { func Start(root string) (chan<- string, <-chan error, *storage) {
ctrlChannel := make(chan string) ctrlChannel := make(chan string)
errorChannel := make(chan error) errorChannel := make(chan error)
@ -67,7 +67,9 @@ func appendUniq(slice []string, i string) []string {
return append(slice, i) return append(slice, i)
} }
// Bucket Operations /// Bucket Operations
// GET - Service
func (storage *storage) ListBuckets() ([]mstorage.BucketMetadata, error) { func (storage *storage) ListBuckets() ([]mstorage.BucketMetadata, error) {
files, err := ioutil.ReadDir(storage.root) files, err := ioutil.ReadDir(storage.root)
if err != nil { if err != nil {
@ -92,6 +94,7 @@ func (storage *storage) ListBuckets() ([]mstorage.BucketMetadata, error) {
return metadataList, nil return metadataList, nil
} }
// PUT - Bucket
func (storage *storage) StoreBucket(bucket string) error { func (storage *storage) StoreBucket(bucket string) error {
storage.lock.Lock() storage.lock.Lock()
defer storage.lock.Unlock() defer storage.lock.Unlock()
@ -119,6 +122,7 @@ func (storage *storage) StoreBucket(bucket string) error {
return nil return nil
} }
// GET - Bucket policy
func (storage *storage) GetBucketPolicy(bucket string) (interface{}, error) { func (storage *storage) GetBucketPolicy(bucket string) (interface{}, error) {
storage.lock.Lock() storage.lock.Lock()
defer storage.lock.Unlock() defer storage.lock.Unlock()
@ -163,6 +167,7 @@ func (storage *storage) GetBucketPolicy(bucket string) (interface{}, error) {
} }
// PUT - Bucket policy
func (storage *storage) StoreBucketPolicy(bucket string, policy interface{}) error { func (storage *storage) StoreBucketPolicy(bucket string, policy interface{}) error {
storage.lock.Lock() storage.lock.Lock()
defer storage.lock.Unlock() defer storage.lock.Unlock()
@ -203,8 +208,9 @@ func (storage *storage) StoreBucketPolicy(bucket string, policy interface{}) err
return nil return nil
} }
// Object Operations /// Object Operations
// GET Object
func (storage *storage) CopyObjectToWriter(w io.Writer, bucket string, object string) (int64, error) { func (storage *storage) CopyObjectToWriter(w io.Writer, bucket string, object string) (int64, error) {
// validate bucket // validate bucket
if mstorage.IsValidBucket(bucket) == false { if mstorage.IsValidBucket(bucket) == false {
@ -247,6 +253,7 @@ func (storage *storage) CopyObjectToWriter(w io.Writer, bucket string, object st
return count, nil return count, nil
} }
// HEAD Object
func (storage *storage) GetObjectMetadata(bucket string, object string) (mstorage.ObjectMetadata, error) { func (storage *storage) GetObjectMetadata(bucket string, object string) (mstorage.ObjectMetadata, error) {
if mstorage.IsValidBucket(bucket) == false { if mstorage.IsValidBucket(bucket) == false {
return mstorage.ObjectMetadata{}, mstorage.BucketNameInvalid{Bucket: bucket} return mstorage.ObjectMetadata{}, mstorage.BucketNameInvalid{Bucket: bucket}
@ -340,10 +347,16 @@ func delimiter(path, delimiter string) string {
type ByObjectKey []mstorage.ObjectMetadata type ByObjectKey []mstorage.ObjectMetadata
func (b ByObjectKey) Len() int { return len(b) } // Len
func (b ByObjectKey) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b ByObjectKey) Len() int { return len(b) }
// Swap
func (b ByObjectKey) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
// Less
func (b ByObjectKey) Less(i, j int) bool { return b[i].Key < b[j].Key } func (b ByObjectKey) Less(i, j int) bool { return b[i].Key < b[j].Key }
// GET bucket (list objects)
func (storage *storage) ListObjects(bucket string, resources mstorage.BucketResourcesMetadata) ([]mstorage.ObjectMetadata, mstorage.BucketResourcesMetadata, error) { func (storage *storage) ListObjects(bucket string, resources mstorage.BucketResourcesMetadata) ([]mstorage.ObjectMetadata, mstorage.BucketResourcesMetadata, error) {
p := Path{} p := Path{}
p.files = make(map[string]os.FileInfo) p.files = make(map[string]os.FileInfo)
@ -388,7 +401,7 @@ func (storage *storage) ListObjects(bucket string, resources mstorage.BucketReso
} }
metadataList = append(metadataList, metadata) metadataList = append(metadataList, metadata)
case delimited != "": case delimited != "":
resources.CommonPrefixes = helpers.appendUniq(resources.CommonPrefixes, delimited) resources.CommonPrefixes = appendUniq(resources.CommonPrefixes, delimited)
} }
case resources.Delimiter != "" && strings.HasPrefix(name, resources.Prefix): case resources.Delimiter != "" && strings.HasPrefix(name, resources.Prefix):
delimited := delimiter(name, resources.Delimiter) delimited := delimiter(name, resources.Delimiter)
@ -403,7 +416,7 @@ func (storage *storage) ListObjects(bucket string, resources mstorage.BucketReso
} }
metadataList = append(metadataList, metadata) metadataList = append(metadataList, metadata)
case delimited != "": case delimited != "":
resources.CommonPrefixes = helpers.AppendUniqStr(resources.CommonPrefixes, delimited) resources.CommonPrefixes = appendUniq(resources.CommonPrefixes, delimited)
} }
case strings.HasPrefix(name, resources.Prefix): case strings.HasPrefix(name, resources.Prefix):
metadata := mstorage.ObjectMetadata{ metadata := mstorage.ObjectMetadata{
@ -422,6 +435,7 @@ ret:
return metadataList, resources, nil return metadataList, resources, nil
} }
// PUT object
func (storage *storage) StoreObject(bucket, key, contentType string, data io.Reader) error { func (storage *storage) StoreObject(bucket, key, contentType string, data io.Reader) error {
// TODO Commits should stage then move instead of writing directly // TODO Commits should stage then move instead of writing directly
storage.lock.Lock() storage.lock.Lock()

View File

@ -67,6 +67,7 @@ type BucketResourcesMetadata struct {
Notification string Notification string
} }
// Verify Bucket name in accordance with http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html
func IsValidBucket(bucket string) bool { func IsValidBucket(bucket string) bool {
if len(bucket) < 3 || len(bucket) > 63 { if len(bucket) < 3 || len(bucket) > 63 {
return false return false
@ -82,6 +83,7 @@ func IsValidBucket(bucket string) bool {
return match return match
} }
// Verify Object name in accordance with http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
func IsValidObject(object string) bool { func IsValidObject(object string) bool {
if len(object) > 1024 || len(object) == 0 { if len(object) > 1024 || len(object) == 0 {
return false return false

View File

@ -24,6 +24,7 @@ import (
. "gopkg.in/check.v1" . "gopkg.in/check.v1"
) )
// API test suite
func APITestSuite(c *C, create func() Storage) { func APITestSuite(c *C, create func() Storage) {
testCreateBucket(c, create) testCreateBucket(c, create)
testMultipleObjectCreation(c, create) testMultipleObjectCreation(c, create)

View File

@ -51,6 +51,14 @@ type ImplementationError struct {
Err error Err error
} }
type BackendCorrupted BackendError
type BucketPolicyNotFound GenericBucketError
type BucketNameInvalid GenericBucketError
type BucketExists GenericBucketError
type BucketNotFound GenericBucketError
type ObjectNameInvalid GenericObjectError
// Return string an error formatted as the given text
func (self ImplementationError) Error() string { func (self ImplementationError) Error() string {
error := "" error := ""
if self.Bucket != "" { if self.Bucket != "" {
@ -63,6 +71,7 @@ func (self ImplementationError) Error() string {
return error return error
} }
// Wrapper function for error object
func EmbedError(bucket, object string, err error) ImplementationError { func EmbedError(bucket, object string, err error) ImplementationError {
return ImplementationError{ return ImplementationError{
Bucket: bucket, Bucket: bucket,
@ -71,45 +80,47 @@ func EmbedError(bucket, object string, err error) ImplementationError {
} }
} }
type BackendCorrupted BackendError // Return string an error formatted as the given text
type BucketPolicyNotFound GenericBucketError
type BucketNameInvalid GenericBucketError
type BucketExists GenericBucketError
type BucketNotFound GenericBucketError
type ObjectNameInvalid GenericObjectError
func (self BucketPolicyNotFound) Error() string { func (self BucketPolicyNotFound) Error() string {
return "Bucket policy not found for: " + self.Bucket return "Bucket policy not found for: " + self.Bucket
} }
// Return string an error formatted as the given text
func (self ObjectNotFound) Error() string { func (self ObjectNotFound) Error() string {
return "Object not Found: " + self.Bucket + "#" + self.Object return "Object not Found: " + self.Bucket + "#" + self.Object
} }
// Return string an error formatted as the given text
func (self ApiNotImplemented) Error() string { func (self ApiNotImplemented) Error() string {
return "Api not implemented: " + self.Api return "Api not implemented: " + self.Api
} }
// Return string an error formatted as the given text
func (self ObjectExists) Error() string { func (self ObjectExists) Error() string {
return "Object exists: " + self.Bucket + "#" + self.Key return "Object exists: " + self.Bucket + "#" + self.Key
} }
// Return string an error formatted as the given text
func (self BucketNameInvalid) Error() string { func (self BucketNameInvalid) Error() string {
return "Bucket name invalid: " + self.Bucket return "Bucket name invalid: " + self.Bucket
} }
// Return string an error formatted as the given text
func (self BucketExists) Error() string { func (self BucketExists) Error() string {
return "Bucket exists: " + self.Bucket return "Bucket exists: " + self.Bucket
} }
// Return string an error formatted as the given text
func (self BucketNotFound) Error() string { func (self BucketNotFound) Error() string {
return "Bucket not Found: " + self.Bucket return "Bucket not Found: " + self.Bucket
} }
// Return string an error formatted as the given text
func (self ObjectNameInvalid) Error() string { func (self ObjectNameInvalid) Error() string {
return "Object name invalid: " + self.Bucket + "#" + self.Object return "Object name invalid: " + self.Bucket + "#" + self.Object
} }
// Return string an error formatted as the given text
func (self BackendCorrupted) Error() string { func (self BackendCorrupted) Error() string {
return "Backend corrupted: " + self.Path return "Backend corrupted: " + self.Path
} }

View File

@ -23,6 +23,9 @@ import (
var castanagoliTable = crc32.MakeTable(crc32.Castagnoli) var castanagoliTable = crc32.MakeTable(crc32.Castagnoli)
/// Convenience functions
// Single caller crc helper
func Sum32(buffer []byte) uint32 { func Sum32(buffer []byte) uint32 {
crc := crc32.New(castanagoliTable) crc := crc32.New(castanagoliTable)
crc.Reset() crc.Reset()
@ -30,6 +33,7 @@ func Sum32(buffer []byte) uint32 {
return crc.Sum32() return crc.Sum32()
} }
// Low memory footprint io.Reader based crc helper
func Sum(reader io.Reader) (uint32, error) { func Sum(reader io.Reader) (uint32, error) {
h := New() h := New()
var err error var err error

View File

@ -26,17 +26,22 @@ func New() hash.Hash32 {
return &digest{crc: 0} return &digest{crc: 0}
} }
// Return size of crc
func (d *digest) Size() int { return Size } func (d *digest) Size() int { return Size }
// Stub
func (d *digest) BlockSize() int { return 1 } func (d *digest) BlockSize() int { return 1 }
// Get crc in bytes
func (d *digest) Sum(in []byte) []byte { func (d *digest) Sum(in []byte) []byte {
s := d.crc s := d.crc
return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s)) return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
} }
// Return current crc in digest object
func (d *digest) Sum32() uint32 { return d.crc } func (d *digest) Sum32() uint32 { return d.crc }
// Reset default crc
func (d *digest) Reset() { d.crc = 0 } func (d *digest) Reset() { d.crc = 0 }
// Update returns the result of adding the bytes in p to the crc. // Update returns the result of adding the bytes in p to the crc.
@ -44,13 +49,15 @@ func (d *digest) update(crc uint32, p []byte) uint32 {
return updateCastanagoliPCL(crc, p) return updateCastanagoliPCL(crc, p)
} }
// Write data
func (d *digest) Write(p []byte) (n int, err error) { func (d *digest) Write(p []byte) (n int, err error) {
d.crc = d.update(d.crc, p) d.crc = d.update(d.crc, p)
return len(p), nil return len(p), nil
} }
// Convenience functions /// Convenience functions
// Single caller crc helper
func Sum32(data []byte) uint32 { func Sum32(data []byte) uint32 {
crc32 := New() crc32 := New()
crc32.Reset() crc32.Reset()
@ -58,6 +65,7 @@ func Sum32(data []byte) uint32 {
return crc32.Sum32() return crc32.Sum32()
} }
// Low memory footprint io.Reader based crc helper
func Sum(reader io.Reader) (uint32, error) { func Sum(reader io.Reader) (uint32, error) {
h := New() h := New()
var err error var err error

View File

@ -17,6 +17,7 @@
package config package config
import ( import (
"io/ioutil"
"os" "os"
"path" "path"
"sync" "sync"

View File

@ -21,6 +21,7 @@ import (
"io" "io"
) )
// Low memory footprint io.Reader based md5sum helper
func Sum(reader io.Reader) ([]byte, error) { func Sum(reader io.Reader) ([]byte, error) {
hash := md5.New() hash := md5.New()
var err error var err error

View File

@ -40,6 +40,7 @@ type digest struct {
len uint64 len uint64
} }
// Reset digest
func (d *digest) Reset() { func (d *digest) Reset() {
d.h[0] = init0 d.h[0] = init0
d.h[1] = init1 d.h[1] = init1
@ -68,10 +69,13 @@ func block(dig *digest, p []byte) {
} }
} }
// Return output size
func (d *digest) Size() int { return Size } func (d *digest) Size() int { return Size }
// Return checksum blocksize
func (d *digest) BlockSize() int { return BlockSize } func (d *digest) BlockSize() int { return BlockSize }
// Write to digest
func (d *digest) Write(p []byte) (nn int, err error) { func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p) nn = len(p)
d.len += uint64(nn) d.len += uint64(nn)
@ -95,6 +99,7 @@ func (d *digest) Write(p []byte) (nn int, err error) {
return return
} }
// Return checksum bytes
func (d0 *digest) Sum(in []byte) []byte { func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing. // Make a copy of d0 so that caller can keep writing and summing.
d := *d0 d := *d0
@ -102,6 +107,7 @@ func (d0 *digest) Sum(in []byte) []byte {
return append(in, hash[:]...) return append(in, hash[:]...)
} }
// Intermediate checksum function
func (d *digest) checkSum() [Size]byte { func (d *digest) checkSum() [Size]byte {
len := d.len len := d.len
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
@ -135,8 +141,9 @@ func (d *digest) checkSum() [Size]byte {
return digest return digest
} }
// Convenience functions /// Convenience functions
// Single caller sha1 helper
func Sum1(data []byte) [Size]byte { func Sum1(data []byte) [Size]byte {
var d digest var d digest
d.Reset() d.Reset()
@ -144,6 +151,7 @@ func Sum1(data []byte) [Size]byte {
return d.checkSum() return d.checkSum()
} }
// io.Reader based streaming sha1 helper
func Sum(reader io.Reader) ([]byte, error) { func Sum(reader io.Reader) ([]byte, error) {
h := New() h := New()
var err error var err error

View File

@ -1,65 +0,0 @@
// +build ignore
//
// Mini Object Storage, (C) 2015 Minio, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package main
import (
"crypto/sha1"
"encoding/hex"
"fmt"
"io"
"os"
"time"
sha1intel "github.com/minio-io/minio/pkg/utils/crypto/sha1"
)
func Sum(reader io.Reader) ([]byte, error) {
k := sha1.New()
var err error
for err == nil {
length := 0
byteBuffer := make([]byte, 1024*1024)
length, err = reader.Read(byteBuffer)
byteBuffer = byteBuffer[0:length]
k.Write(byteBuffer)
}
if err != io.EOF {
return nil, err
}
return k.Sum(nil), nil
}
func main() {
fmt.Println("-- start")
file1, _ := os.Open("filename1")
defer file1.Close()
stark := time.Now()
sum, _ := Sum(file1)
endk := time.Since(stark)
file2, _ := os.Open("filename2")
defer file2.Close()
starth := time.Now()
sumAVX2, _ := sha1intel.Sum(file2)
endh := time.Since(starth)
fmt.Println("std(", endk, ")", "avx2(", endh, ")")
fmt.Println(hex.EncodeToString(sum), hex.EncodeToString(sumAVX2))
}

View File

@ -43,6 +43,7 @@ type digest struct {
len uint64 len uint64
} }
// Reset digest back to default
func (d *digest) Reset() { func (d *digest) Reset() {
d.h[0] = init0 d.h[0] = init0
d.h[1] = init1 d.h[1] = init1
@ -74,12 +75,13 @@ func New() hash.Hash {
return d return d
} }
func (d *digest) Size() int { // Return size of checksum
return Size func (d *digest) Size() int { return Size }
}
// Return blocksize of checksum
func (d *digest) BlockSize() int { return BlockSize } func (d *digest) BlockSize() int { return BlockSize }
// Write to digest
func (d *digest) Write(p []byte) (nn int, err error) { func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p) nn = len(p)
d.len += uint64(nn) d.len += uint64(nn)
@ -103,6 +105,7 @@ func (d *digest) Write(p []byte) (nn int, err error) {
return return
} }
// Return sha256 sum in bytes
func (d0 *digest) Sum(in []byte) []byte { func (d0 *digest) Sum(in []byte) []byte {
// Make a copy of d0 so that caller can keep writing and summing. // Make a copy of d0 so that caller can keep writing and summing.
d := *d0 d := *d0
@ -110,6 +113,7 @@ func (d0 *digest) Sum(in []byte) []byte {
return append(in, hash[:]...) return append(in, hash[:]...)
} }
// Intermediate checksum function
func (d *digest) checkSum() [Size]byte { func (d *digest) checkSum() [Size]byte {
len := d.len len := d.len
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
@ -145,8 +149,9 @@ func (d *digest) checkSum() [Size]byte {
return digest return digest
} }
// Convenience functions /// Convenience functions
// Single caller sha256 helper
func Sum256(data []byte) [Size]byte { func Sum256(data []byte) [Size]byte {
var d digest var d digest
d.Reset() d.Reset()
@ -154,6 +159,7 @@ func Sum256(data []byte) [Size]byte {
return d.checkSum() return d.checkSum()
} }
// io.Reader based streaming sha256 helper
func Sum(reader io.Reader) ([]byte, error) { func Sum(reader io.Reader) ([]byte, error) {
h := New() h := New()
var err error var err error

View File

@ -1,81 +0,0 @@
// +build ignore
//
// Mini Object Storage, (C) 2015 Minio, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"os"
"time"
sha256intel "github.com/minio-io/minio/pkg/utils/crypto/sha256"
)
func SumIntel(reader io.Reader) ([]byte, error) {
h := sha256intel.New()
var err error
for err == nil {
length := 0
byteBuffer := make([]byte, 1024*1024)
length, err = reader.Read(byteBuffer)
byteBuffer = byteBuffer[0:length]
h.Write(byteBuffer)
}
if err != io.EOF {
return nil, err
}
return h.Sum(nil), nil
}
func Sum(reader io.Reader) ([]byte, error) {
k := sha256.New()
var err error
for err == nil {
length := 0
byteBuffer := make([]byte, 1024*1024)
length, err = reader.Read(byteBuffer)
byteBuffer = byteBuffer[0:length]
k.Write(byteBuffer)
}
if err != io.EOF {
return nil, err
}
return k.Sum(nil), nil
}
func main() {
fmt.Println("-- start")
file1, _ := os.Open("filename1")
defer file1.Close()
stark := time.Now()
sum, _ := Sum(file1)
endk := time.Since(stark)
file2, _ := os.Open("filename2")
defer file2.Close()
starth := time.Now()
sumSSE, _ := SumIntel(file2)
endh := time.Since(starth)
fmt.Println("std(", endk, ")", "ssse3(", endh, ")")
fmt.Println(hex.EncodeToString(sum), hex.EncodeToString(sumSSE))
}

View File

@ -155,9 +155,9 @@ func (d *digest) checkSum() [Size]byte {
return digest return digest
} }
// Convenience functions /// Convenience functions
// Single caller function returns [Size]byte // Single caller sha512 helper
func Sum512(data []byte) [Size]byte { func Sum512(data []byte) [Size]byte {
var d digest var d digest
d.Reset() d.Reset()
@ -165,7 +165,7 @@ func Sum512(data []byte) [Size]byte {
return d.checkSum() return d.checkSum()
} }
// Takes in io.Reader, low memory footprint checksum // io.Reader based streaming sha512 helper
func Sum(reader io.Reader) ([]byte, error) { func Sum(reader io.Reader) ([]byte, error) {
h := New() h := New()
var err error var err error

View File

@ -1,83 +0,0 @@
// +build ignore
//
// Mini Object Storage, (C) 2015 Minio, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package main
import (
"crypto/sha512"
"encoding/hex"
"fmt"
"io"
"os"
"time"
sha512intel "github.com/minio-io/minio/pkg/utils/crypto/sha512"
)
// Intels processor accelerated sha512 implementation
func SumIntel(reader io.Reader) ([]byte, error) {
h := sha512intel.New()
var err error
for err == nil {
length := 0
byteBuffer := make([]byte, 1024*1024)
length, err = reader.Read(byteBuffer)
byteBuffer = byteBuffer[0:length]
h.Write(byteBuffer)
}
if err != io.EOF {
return nil, err
}
return h.Sum(nil), nil
}
// Golang default implementation
func Sum(reader io.Reader) ([]byte, error) {
k := sha512.New()
var err error
for err == nil {
length := 0
byteBuffer := make([]byte, 1024*1024)
length, err = reader.Read(byteBuffer)
byteBuffer = byteBuffer[0:length]
k.Write(byteBuffer)
}
if err != io.EOF {
return nil, err
}
return k.Sum(nil), nil
}
func main() {
fmt.Println("-- start")
file1, _ := os.Open("filename1")
defer file1.Close()
stark := time.Now()
sum, _ := Sum(file1)
endk := time.Since(stark)
file2, _ := os.Open("filename2")
defer file2.Close()
starth := time.Now()
sumSSE, _ := SumIntel(file2)
endh := time.Since(starth)
fmt.Println("std(", endk, ")", "ssse3(", endh, ")")
fmt.Println(hex.EncodeToString(sum), hex.EncodeToString(sumSSE))
}