func (rs *RecordSet) readFirst() (*Record, error) {
	if rs.first != nil {
		return rs.first, nil
	}
	r, err := rs.r.Read()
	if err != nil {
		return nil, err
	}
	rec := Record(r)
	rs.first = &rec
	return rs.first, nil
}
ReadFirst is an unexported method used by various internal packages
to get the first line of the RecordSet.
package ais
import (
	"bufio"
	"bytes"
	"encoding/csv"
	"errors"
	"fmt"
	"hash"
	"hash/fnv"
	"io"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"
	"github.com/FATHOM5/haversine"
	"github.com/mmcloughlin/geohash"
)
const TimeLayout = `2006-01-02T15:04:05`
const flushThreshold = 250000
var ErrEmptySet = errors.New("ErrEmptySet")
type Matching interface {
	Match(*Record) (bool, error)
}
type Vessel struct {
	MMSI       string
	VesselName string
}
type VesselSet map[Vessel]int
type Field string
type Generator interface {
	Generate(rec Record, index ...int) (Field, error)
}
type Geohasher RecordSet
func NewGeohasher(rs *RecordSet) *Geohasher {
	g := Geohasher(*rs)
	return &g
}
func (g *Geohasher) Generate(rec Record, index ...int) (Field, error) {
	if len(index) != 2 {
		return "", fmt.Errorf("geohash: generate: len(index) must equal" +
			" 2 where the first int is the index of `LAT` and the second int is the index of `LON`")
	}
	indexLat, indexLon := index[0], index[1]
	lat, err := rec.ParseFloat(indexLat)
	if err != nil {
		return "", fmt.Errorf("geohash: unable to parse lat")
	}
	lon, err := rec.ParseFloat(indexLon)
	if err != nil {
		return "", fmt.Errorf("geohash: unable to parse lon")
	}
	hash := geohash.EncodeIntWithPrecision(lat, lon, uint(22))
	return Field(fmt.Sprintf("%#x", hash)), nil
}
type RecordSet struct {
	r     *csv.Reader    
	w     *csv.Writer    
	h     Headers        
	data  io.ReadWriter  
	first *Record        
	stash *Record        
}
func NewRecordSet() *RecordSet {
	rs := new(RecordSet)
	buf := bytes.Buffer{}
	rs.data = &buf
	rs.r = csv.NewReader(&buf)
	rs.w = csv.NewWriter(&buf)
	rs.r.LazyQuotes = true
	rs.r.Comment = '#'
	return rs
}
func OpenRecordSet(filename string) (*RecordSet, error) {
	rs := NewRecordSet()
	f, err := os.OpenFile(filename, os.O_RDWR, 0666)  
	if err != nil {
		return nil, fmt.Errorf("open recordset: %v", err)
	}
	rs.data = f
	rs.r = csv.NewReader(f)
	rs.r.LazyQuotes = true
	rs.r.Comment = '#'
	rs.w = csv.NewWriter(f)
	var h Headers
	h.Fields, err = rs.r.Read()
	if err != nil {
		return nil, fmt.Errorf("open recordset: %v", err)
	}
	rs.h = h
	return rs, nil
}
func (rs *RecordSet) SetHeaders(h Headers) {
	rs.h = h
}
func (rs *RecordSet) Read() (*Record, error) {
	if rec := rs.first; rec != nil {
		rs.first = nil
		return rec, nil
	}
	if rec := rs.stash; rec != nil {
		rs.stash = nil
		return rec, nil
	}
	r, err := rs.r.Read()
	if err == io.EOF {
		return nil, err
	}
	if err != nil {
		return nil, fmt.Errorf("recordset read: %v", err)
	}
	rec := Record(r)
	return &rec, nil
}