// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated by the vanadium vdl tool.
// Source: types.vdl

package nosql

import (
	// VDL system imports
	"v.io/v23/vdl"

	// VDL user imports
	"time"
	"v.io/v23/services/syncbase/nosql"
	_ "v.io/v23/vdlroot/time"
)

// Conflict contains information to fully specify a conflict. Since syncbase
// supports batches there can be one or more rows within the batch that has a
// conflict. Each of these rows will be sent together as part of a single
// conflict. Each row contains an Id of the batch to which it belongs,
// enabling the client to group together rows that are part of a batch. Note
// that a single row can be part of more than one batch.
//
// WriteSet contains rows that were written.
// ReadSet contains rows that were read within a batch corresponding to a row
// within the write set.
// ScanSet contains scans performed within a batch corresponding to a row
// within the write set.
// Batches is a map of unique ids to BatchInfo objects. The id is unique only in
// the context of a given conflict and is otherwise meaningless.
type Conflict struct {
	ReadSet  *ConflictRowSet
	WriteSet *ConflictRowSet
	ScanSet  *ConflictScanSet
	Batches  map[uint64]nosql.BatchInfo
}

func (Conflict) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/syncbase/nosql.Conflict"`
}) {
}

// ConflictRowSet contains a set of rows under conflict. It provides two different
// ways to access the same set.
// ByKey is a map of ConflictRows keyed by the row key.
// ByBatch is a map of []ConflictRows keyed by batch id. This map lets the client
// access all ConflictRows within this set that contain a given hint.
type ConflictRowSet struct {
	ByKey   map[string]ConflictRow
	ByBatch map[uint64][]ConflictRow
}

func (ConflictRowSet) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/syncbase/nosql.ConflictRowSet"`
}) {
}

// ConflictScanSet contains a set of scans under conflict.
// ByBatch is a map of array of ScanOps keyed by batch id.
type ConflictScanSet struct {
	ByBatch map[uint64][]nosql.ScanOp
}

func (ConflictScanSet) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/syncbase/nosql.ConflictScanSet"`
}) {
}

// ConflictRow represents a row under conflict.
// Key is the key for the row.
// LocalValue is the value present in the local db.
// RemoteValue is the value received via sync.
// AncestorValue is the value for the key which is the lowest common
// ancestor of the two values represented by LocalValue and RemoteValue.
// AncestorValue's state is NoExists if the ConflictRow is a part of the read set.
// BatchIds is a list of ids of all the batches that this row belongs to.
type ConflictRow struct {
	Key           string
	LocalValue    Value
	RemoteValue   Value
	AncestorValue Value
	BatchIds      []uint64
}

func (ConflictRow) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/syncbase/nosql.ConflictRow"`
}) {
}

// Resolution contains the application’s reply to a conflict. It must contain a
// resolved value for each conflict row within the WriteSet of the given
// conflict.
// ResultSet is a map of row key to ResolvedRow.
type Resolution struct {
	ResultSet map[string]ResolvedRow
}

func (Resolution) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/syncbase/nosql.Resolution"`
}) {
}

// ResolvedRow represents a result of resolution of a row under conflict.
// Key is the key for the row.
// Result is the result of the conflict resolution. Delete is represented
// by nil.
type ResolvedRow struct {
	Key    string
	Result *Value
}

func (ResolvedRow) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/syncbase/nosql.ResolvedRow"`
}) {
}

// Value contains a specific version of data for the row under conflict along
// with the write timestamp and hints associated with the version.
// State defines whether the value is empty or not. It can be empty for
// reasons like Deleted or Unknown.
// WriteTs is the write timestamp for this value.
type Value struct {
	State   nosql.ValueState
	Val     []byte
	WriteTs time.Time
	// TODO(jlodhia): Since field Selection cannot be package private in VDL,
	// review the ConflictResolution API to see if we should keep this field
	// or not.
	Selection nosql.ValueSelection
}

func (Value) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/syncbase/nosql.Value"`
}) {
}

func init() {
	vdl.Register((*Conflict)(nil))
	vdl.Register((*ConflictRowSet)(nil))
	vdl.Register((*ConflictScanSet)(nil))
	vdl.Register((*ConflictRow)(nil))
	vdl.Register((*Resolution)(nil))
	vdl.Register((*ResolvedRow)(nil))
	vdl.Register((*Value)(nil))
}
