// Map will write in any mutations needed to maintain this timeseries index
// based on the current item and the lastRead item
func (ts *TimeSeries) Map(writer gossie.Writer, item, lastRead interface{}) error {
	uid, t := ts.Marshaler(item)
	b, err := json.Marshal(item)
	if err != nil {
		log.Errorf("Error marshalling item %s", err) // TODO should probably bubble this up
		return err
	}
	rowPrefix := ""
	if ts.SecondaryIndexer != nil {
		rowPrefix = ts.SecondaryIndexer(item)
	}

	// C* ttl for ageing out columns
	var ttl int32
	if ts.Ttler != nil {
		ttl = ts.Ttler(item)
	}

	// always mutate against current marshaled value -- if not zero time
	if !t.IsZero() {
		tsRow := &gossie.Row{
			Key: ts.toRowKey(rowPrefix, t),
			Columns: []*gossie.Column{
				{
					Name:  idTimeToColumnName(uid, t),
					Value: b,
					Ttl:   ttl,
				},
			},
		}
		writer.Insert(ts.Cf, tsRow)
	}

	// old one that's different (and old one not zero)? add deletion...
	if lastRead != nil && !reflect.ValueOf(lastRead).IsNil() {
		lUid, lT := ts.Marshaler(lastRead)
		if ts.SecondaryIndexer != nil {
			lRowPrefix := ts.SecondaryIndexer(lastRead)
			if !lT.IsZero() && (!lT.Equal(t) || lRowPrefix != rowPrefix) {
				writer.DeleteColumns(ts.Cf, ts.toRowKey(lRowPrefix, lT), [][]byte{idTimeToColumnName(lUid, lT)})
			}
		}
	}

	// update index, if we have one defined
	if ts.IndexCf != "" {
		i := newIndex(ts, rowPrefix)
		i.write(writer, t.Truncate(ts.RowGranularity))
	}

	return nil
}
// Delete an item from the timeseries (remove the column entirely)
func (ts *TimeSeries) Delete(writer gossie.Writer, item interface{}) error {
	// While this doesn't currently return any error, adding it to the exposed interface so one can be returned later if
	// necessary (and clients will expect this)
	uid, t := ts.Marshaler(item)
	rowPrefix := ""
	if ts.SecondaryIndexer != nil {
		rowPrefix = ts.SecondaryIndexer(item)
	}
	rowKey := ts.toRowKey(rowPrefix, t)
	columnName := idTimeToColumnName(uid, t)

	writer.DeleteColumns(ts.Cf, rowKey, [][]byte{columnName})
	return nil
}