84 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			84 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package main
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"strings"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const fieldsLength = 4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// result stores the parsed result for a domain
							 | 
						||
| 
								 | 
							
								type result struct {
							 | 
						||
| 
								 | 
							
									domain  string
							 | 
						||
| 
								 | 
							
									page    string
							 | 
						||
| 
								 | 
							
									visits  int
							 | 
						||
| 
								 | 
							
									uniques int
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// add adds the metrics of another result
							 | 
						||
| 
								 | 
							
								func (r result) add(other result) result {
							 | 
						||
| 
								 | 
							
									r.visits += other.visits
							 | 
						||
| 
								 | 
							
									r.uniques += other.uniques
							 | 
						||
| 
								 | 
							
									return r
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// parseFields parses and returns the parsing result
							 | 
						||
| 
								 | 
							
								func parseFields(line string) (r result, err error) {
							 | 
						||
| 
								 | 
							
									fields := strings.Fields(line)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if len(fields) != fieldsLength {
							 | 
						||
| 
								 | 
							
										return r, fmt.Errorf("wrong number of fields %q", fields)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									r.domain = fields[0]
							 | 
						||
| 
								 | 
							
									r.page = fields[1]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									f := new(field)
							 | 
						||
| 
								 | 
							
									r.visits = f.uatoi("visits", fields[2])
							 | 
						||
| 
								 | 
							
									r.uniques = f.uatoi("uniques", fields[3])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return r, f.err
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func fastParseFields(data []byte) (res result, err error) {
							 | 
						||
| 
								 | 
							
									const separator = ' '
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var findex int
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for i, j := 0, 0; i < len(data); i++ {
							 | 
						||
| 
								 | 
							
										c := data[i]
							 | 
						||
| 
								 | 
							
										last := len(data) == i+1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if c != separator && !last {
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if last {
							 | 
						||
| 
								 | 
							
											i = len(data)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch fval := data[j:i]; findex {
							 | 
						||
| 
								 | 
							
										case 0:
							 | 
						||
| 
								 | 
							
											res.domain = string(fval)
							 | 
						||
| 
								 | 
							
										case 1:
							 | 
						||
| 
								 | 
							
											res.page = string(fval)
							 | 
						||
| 
								 | 
							
										case 2:
							 | 
						||
| 
								 | 
							
											res.visits, err = atoi(fval)
							 | 
						||
| 
								 | 
							
										case 3:
							 | 
						||
| 
								 | 
							
											res.uniques, err = atoi(fval)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if err != nil {
							 | 
						||
| 
								 | 
							
											return res, err
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										j = i + 1
							 | 
						||
| 
								 | 
							
										findex++
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if findex != fieldsLength {
							 | 
						||
| 
								 | 
							
										err = fmt.Errorf("wrong number of fields %q", data)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return res, err
							 | 
						||
| 
								 | 
							
								}
							 |