MCPcopy Create free account
hub / github.com/devaccuracy/ledgerforge / processCSVRowsParallel

Function processCSVRowsParallel

internal/files/files.go:252–317  ·  view source on GitHub ↗

Parallel CSV processing with worker pool

(ctx context.Context, uploadID, source string, csvReader *csv.Reader, columnMap map[string]int, store StoreFunc)

Source from the content-addressed store, hash-verified

250
251// Parallel CSV processing with worker pool
252func processCSVRowsParallel(ctx context.Context, uploadID, source string, csvReader *csv.Reader, columnMap map[string]int, store StoreFunc) (int, error) {
253 workerCount := runtime.NumCPU()
254 if workerCount > DefaultWorkerCount {
255 workerCount = DefaultWorkerCount
256 }
257
258 rowChan := make(chan []string, DefaultChannelSize)
259 errChan := make(chan error, workerCount)
260 var wg sync.WaitGroup
261 totalCount := int64(0)
262 var countMu sync.Mutex
263
264 // Start workers
265 for i := 0; i < workerCount; i++ {
266 wg.Add(1)
267 go func() {
268 defer wg.Done()
269 processWorker(ctx, uploadID, source, rowChan, columnMap, store, &totalCount, &countMu, errChan)
270 }()
271 }
272
273 // Read CSV rows and send to workers
274 go func() {
275 rowNum := 1
276 for {
277 record, err := csvReader.Read()
278 if err == io.EOF {
279 break
280 }
281 if err != nil {
282 errChan <- fmt.Errorf("error reading row %d: %w", rowNum, err)
283 continue
284 }
285
286 rowNum++
287
288 // Make a copy since csvReader.ReuseRecord is true
289 recordCopy := make([]string, len(record))
290 copy(recordCopy, record)
291
292 select {
293 case <-ctx.Done():
294 close(rowChan)
295 return
296 case rowChan <- recordCopy:
297 }
298 }
299 close(rowChan)
300 }()
301
302 // Wait for workers to finish
303 wg.Wait()
304 close(errChan)
305
306 // Collect errors
307 var errs []error
308 for err := range errChan {
309 errs = append(errs, err)

Callers 1

ProcessCSVFunction · 0.85

Calls 1

processWorkerFunction · 0.85

Tested by

no test coverage detected