diff --git a/pkg/file/file.go b/pkg/file/file.go index 1b339df..7481f36 100644 --- a/pkg/file/file.go +++ b/pkg/file/file.go @@ -33,7 +33,7 @@ type File interface { Parse(record []byte) error Bytes() []byte String(newline bool) string - StringWithConcurrency(newline bool, concurrency int) string + ConcurrentString(newline bool, goroutines int) string Validate() error } diff --git a/pkg/file/file_instance.go b/pkg/file/file_instance.go index 5efdd14..ab95a80 100644 --- a/pkg/file/file_instance.go +++ b/pkg/file/file_instance.go @@ -10,6 +10,7 @@ import ( "fmt" "math" "reflect" + "runtime" "strings" "sync" "unicode" @@ -254,15 +255,21 @@ func (f *fileInstance) Parse(record []byte) error { return nil } +var ( + // defaultStringConcurrency is the default number of goroutines to use for File.String() calls, + // which is the number of CPUs detectable by Go. + defaultStringConcurrency = runtime.NumCPU() +) + // String writes the File struct to raw string. func (f *fileInstance) String(isNewLine bool) string { - return f.StringWithConcurrency(isNewLine, 1) + return f.ConcurrentString(isNewLine, defaultStringConcurrency) } -// StringWithConcurrency augments String with a given number of concurrent goroutines. -func (f *fileInstance) StringWithConcurrency(isNewLine bool, concurrency int) string { - if concurrency < 1 { - concurrency = 1 +// ConcurrentString writes the File struct to a string by concurrently generating rows. +func (f *fileInstance) ConcurrentString(isNewLine bool, goroutines int) string { + if goroutines < 1 { + goroutines = 1 } var buf strings.Builder @@ -277,9 +284,9 @@ func (f *fileInstance) StringWithConcurrency(isNewLine bool, concurrency int) st // Data Block data := "" - pageSize := int(math.Ceil(float64(len(f.Bases)) / float64(concurrency))) + pageSize := int(math.Ceil(float64(len(f.Bases)) / float64(goroutines))) basePages := [][]lib.Record{} - dataPages := make([]string, concurrency) + dataPages := make([]string, goroutines) for i := 0; i < len(f.Bases); i += pageSize { end := i + pageSize if end > len(f.Bases) { diff --git a/pkg/file/file_test.go b/pkg/file/file_test.go index 3bdd5b0..fb3f5a0 100644 --- a/pkg/file/file_test.go +++ b/pkg/file/file_test.go @@ -77,7 +77,7 @@ func (t *FileTest) TestJsonWithUnpackedVariableBlocked(c *check.C) { rawStr := strings.ReplaceAll(string(raw), "\r\n", "\n") c.Assert(strings.Compare(f.String(true), rawStr), check.Equals, 0) - c.Assert(strings.Compare(f.StringWithConcurrency(true, 2), rawStr), check.Equals, 0) + c.Assert(strings.Compare(f.ConcurrentString(true, 2), rawStr), check.Equals, 0) buf, err := json.Marshal(f) c.Assert(err, check.IsNil) @@ -321,7 +321,7 @@ func (t *FileTest) TestCreateFile(c *check.C) { c.Assert(err, check.IsNil) c.Assert(strings.Compare(f.String(false), string(raw)), check.Equals, 0) - c.Assert(strings.Compare(f.StringWithConcurrency(false, 2), string(raw)), check.Equals, 0) + c.Assert(strings.Compare(f.ConcurrentString(false, 2), string(raw)), check.Equals, 0) } func (t *FileTest) TestNewFileFromReader(c *check.C) { @@ -335,7 +335,7 @@ func (t *FileTest) TestNewFileFromReader(c *check.C) { c.Assert(err, check.IsNil) c.Assert(strings.Compare(f.String(false), string(raw)), check.Equals, 0) - c.Assert(strings.Compare(f.StringWithConcurrency(false, 2), string(raw)), check.Equals, 0) + c.Assert(strings.Compare(f.ConcurrentString(false, 2), string(raw)), check.Equals, 0) } func (t *FileTest) TestCreateFileFailed(c *check.C) {