func unmarshalCSV(record []string) *gtfsrt.VehicleLocation {
	vehicleID, speedStr, lonStr, routeID, timeStr, latStr, tripID := record[0], record[2], record[3], record[4], record[6], record[7], record[8]
	speed, _ := strconv.ParseFloat(speedStr, 32)
	lon, _ := strconv.ParseFloat(lonStr, 32)
	lat, _ := strconv.ParseFloat(latStr, 32)
	timestamp, _ := time.Parse(Iso8601Format, timeStr)
	loc := &gtfsrt.VehicleLocation{
		VehicleId: proto.String(vehicleID),
		Timestamp: proto.Int64(timestamp.Unix()),
		Speed:     proto.Float32(float32(speed)),
		RouteId:   proto.String(routeID),
		TripId:    proto.String(tripID),
		Latitude:  proto.Float32(float32(lat)),
		Longitude: proto.Float32(float32(lon)),
	}
	return loc
}
assumes CSV field names in order
vehicle_id,dist_traveled,speed,lon,route_id,trip_headsign,timestamp,lat,trip_id
package tools
import (
	"bytes"
	"encoding/csv"
	"github.com/boltdb/bolt"
	"github.com/cheggaaa/pb"
	"github.com/golang/protobuf/proto"
	"github.com/scascketta/capmetricsd/daemon"
	"github.com/scascketta/capmetricsd/daemon/gtfsrt"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"sync"
	"time"
)
const (
	Iso8601Format = "2006-01-02T15:04:05-07:00"
)
func countLines(fname string) (int, error) {
	r, err := os.Open(fname)
	if err != nil {
		log.Println(err)
	}
	defer r.Close()
	buf := make([]byte, 8196)
	count := 0
	lineSep := []byte{'\n'}
	for {
		c, err := r.Read(buf)
		if err != nil && err != io.EOF {
			return count, err
		}
		count += bytes.Count(buf[:c], lineSep)
		if err == io.EOF {
			break
		}
	}
	return count, nil
}
func countBucketKeys(db *bolt.DB) int {
	count := 0
	db.Update(func(tx *bolt.Tx) error {
		bucket, _ := tx.CreateBucketIfNotExists([]byte(daemon.BUCKET_NAME))
		cursor := bucket.Cursor()
		for k, _ := cursor.First(); k != nil; k, _ = cursor.Next() {
			count += 1
		}
		return nil
	})
	return count
}