Skip to content

Commit

Permalink
Support primary and secondary client indexes
Browse files Browse the repository at this point in the history
Introduces two types of client indexes: primary and secondary. Primary
indexes are verified to no be duplicate at transaction verification,
when enable, otherwise there is no difference between them.

Signed-off-by: Jaime Caamaño Ruiz <jcaamano@redhat.com>
  • Loading branch information
jcaamano committed Jun 1, 2022
1 parent 95e93f3 commit b8d9ff4
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
22 changes: 15 additions & 7 deletions cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,14 @@ type indexType uint

const (
schemaIndexType indexType = iota
clientIndexType
primaryClientIndexType
secondaryClientIndexType
)

func clientIndexTypeToCacheIndexType(modelIndexType model.IndexType) indexType {
return indexType(modelIndexType + 1)
}

// indexSpec contains details about an index
type indexSpec struct {
index index
Expand All @@ -94,13 +99,17 @@ type indexSpec struct {
}

func (s indexSpec) isClientIndex() bool {
return s.indexType == clientIndexType
return s.indexType >= primaryClientIndexType
}

func (s indexSpec) isSchemaIndex() bool {
return s.indexType == schemaIndexType
}

func (s indexSpec) isPrimaryIndex() bool {
return s.indexType < secondaryClientIndexType
}

// newIndex builds a index from a list of columns
func newIndexFromColumns(columns ...string) index {
sort.Strings(columns)
Expand Down Expand Up @@ -372,10 +381,8 @@ func (r *RowCache) IndexExists(row model.Model) error {
}
uuid := field.(string)
for _, indexSpec := range r.indexSpecs {
if !indexSpec.isSchemaIndex() {
// Given the ordered indexSpecs, we can break here if we reach the
// first non schema index
break
if !indexSpec.isPrimaryIndex() {
continue
}
index := indexSpec.index
val, err := valueFromIndex(info, indexSpec.columns)
Expand Down Expand Up @@ -1103,7 +1110,8 @@ func newRowCache(name string, dbModel model.DatabaseModel, dataType reflect.Type
if _, ok := indexes[index]; ok {
continue
}
spec := indexSpec{index: index, columns: columnKeys, indexType: clientIndexType}
indexType := clientIndexTypeToCacheIndexType(clientIndex.Type)
spec := indexSpec{index: index, columns: columnKeys, indexType: indexType}
r.indexSpecs = append(r.indexSpecs, spec)
indexes[index] = spec
}
Expand Down
14 changes: 14 additions & 0 deletions model/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,22 @@ type ColumnKey struct {
Key interface{}
}

// IndexType is the type of client index
type IndexType uint

const (
// PrimaryIndexType are client indexes for which uniqueness is optionally
// enforced in the context of a specific client instance transaction before
// it is sent to the server.
PrimaryIndexType IndexType = iota
// SecondaryIndexType are indexes for which uniqueness is not enforced.
SecondaryIndexType
)

// ClientIndex defines a client index by a set of columns
type ClientIndex struct {
Columns []ColumnKey
Type IndexType
}

// ClientDBModel contains the client information needed to build a DatabaseModel
Expand Down Expand Up @@ -161,6 +174,7 @@ func copyIndexes(src map[string][]ClientIndex) map[string][]ClientIndex {
dst[table] = make([]ClientIndex, 0, len(indexSets))
for _, indexSet := range indexSets {
indexSetCopy := ClientIndex{
Type: indexSet.Type,
Columns: make([]ColumnKey, len(indexSet.Columns)),
}
copy(indexSetCopy.Columns, indexSet.Columns)
Expand Down

0 comments on commit b8d9ff4

Please sign in to comment.