Skip to content

Commit

Permalink
feat: Enable Indexing of array fields (#3092)
Browse files Browse the repository at this point in the history
## Relevant issue(s)

Resolves #2279

## Description

Enable indexing of array fields.

This change also adds `Equal` method to `NormalValue`.
  • Loading branch information
islamaliev authored Oct 4, 2024
1 parent 01030fd commit bc93bff
Show file tree
Hide file tree
Showing 35 changed files with 5,216 additions and 298 deletions.
6 changes: 4 additions & 2 deletions client/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ type IndexDescription struct {

// CollectionIndex is an interface for indexing documents in a collection.
type CollectionIndex interface {
// Save indexes a document by storing it
// Save indexes a document by storing indexed field values.
// It doesn't retire previous values. For this [Update] should be used.
Save(context.Context, datastore.Txn, *Document) error
// Update updates an existing document in the index
// Update updates an existing document in the index.
// It removes the previous indexed field values and stores the new ones.
Update(context.Context, datastore.Txn, *Document, *Document) error
// Delete deletes an existing document from the index
Delete(context.Context, datastore.Txn, *Document) error
Expand Down
62 changes: 62 additions & 0 deletions client/normal_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ func (v normalBoolArray) BoolArray() ([]bool, bool) {
return v.val, true
}

func (v normalBoolArray) Equal(other NormalValue) bool {
return areNormalArraysEqual(v.val, other.BoolArray)
}

type normalIntArray struct {
baseArrayNormalValue[[]int64]
}
Expand All @@ -49,6 +53,10 @@ func (v normalIntArray) IntArray() ([]int64, bool) {
return v.val, true
}

func (v normalIntArray) Equal(other NormalValue) bool {
return areNormalArraysEqual(v.val, other.IntArray)
}

type normalFloatArray struct {
baseArrayNormalValue[[]float64]
}
Expand All @@ -57,6 +65,10 @@ func (v normalFloatArray) FloatArray() ([]float64, bool) {
return v.val, true
}

func (v normalFloatArray) Equal(other NormalValue) bool {
return areNormalArraysEqual(v.val, other.FloatArray)
}

type normalStringArray struct {
baseArrayNormalValue[[]string]
}
Expand All @@ -65,6 +77,10 @@ func (v normalStringArray) StringArray() ([]string, bool) {
return v.val, true
}

func (v normalStringArray) Equal(other NormalValue) bool {
return areNormalArraysEqual(v.val, other.StringArray)
}

type normalBytesArray struct {
baseArrayNormalValue[[][]byte]
}
Expand All @@ -73,6 +89,13 @@ func (v normalBytesArray) BytesArray() ([][]byte, bool) {
return v.val, true
}

func (v normalBytesArray) Equal(other NormalValue) bool {
if otherVal, ok := other.BytesArray(); ok {
return are2DArraysEqual(v.val, otherVal)
}
return false
}

type normalTimeArray struct {
baseArrayNormalValue[[]time.Time]
}
Expand All @@ -81,6 +104,10 @@ func (v normalTimeArray) TimeArray() ([]time.Time, bool) {
return v.val, true
}

func (v normalTimeArray) Equal(other NormalValue) bool {
return areNormalArraysEqual(v.val, other.TimeArray)
}

type normalDocumentArray struct {
baseArrayNormalValue[[]*Document]
}
Expand All @@ -89,6 +116,10 @@ func (v normalDocumentArray) DocumentArray() ([]*Document, bool) {
return v.val, true
}

func (v normalDocumentArray) Equal(other NormalValue) bool {
return areNormalArraysEqual(v.val, other.DocumentArray)
}

// NewNormalBoolArray creates a new NormalValue that represents a `[]bool` value.
func NewNormalBoolArray(val []bool) NormalValue {
return normalBoolArray{newBaseArrayNormalValue(val)}
Expand Down Expand Up @@ -147,3 +178,34 @@ func normalizeCharsArr[R string | []byte, T string | []byte](val []T) []R {
}
return arr
}

func areArraysEqual[T comparable](arr1, arr2 []T) bool {
if len(arr1) != len(arr2) {
return false
}
for i, v := range arr1 {
if v != arr2[i] {
return false
}
}
return true
}

func areNormalArraysEqual[T comparable](val []T, f func() ([]T, bool)) bool {
if otherVal, ok := f(); ok {
return areArraysEqual(val, otherVal)
}
return false
}

func are2DArraysEqual[T comparable](arr1, arr2 [][]T) bool {
if len(arr1) != len(arr2) {
return false
}
for i, v := range arr1 {
if !areArraysEqual(v, arr2[i]) {
return false
}
}
return true
}
70 changes: 70 additions & 0 deletions client/normal_array_of_nillables.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package client

import (
"bytes"
"time"

"github.com/sourcenetwork/immutable"
Expand All @@ -25,6 +26,10 @@ func (v normalNillableBoolArray) NillableBoolArray() ([]immutable.Option[bool],
return v.val, true
}

func (v normalNillableBoolArray) Equal(other NormalValue) bool {
return areNormalArraysOfNillablesEqual(v.val, other.NillableBoolArray)
}

type normalNillableIntArray struct {
baseArrayNormalValue[[]immutable.Option[int64]]
}
Expand All @@ -33,6 +38,10 @@ func (v normalNillableIntArray) NillableIntArray() ([]immutable.Option[int64], b
return v.val, true
}

func (v normalNillableIntArray) Equal(other NormalValue) bool {
return areNormalArraysOfNillablesEqual(v.val, other.NillableIntArray)
}

type normalNillableFloatArray struct {
baseArrayNormalValue[[]immutable.Option[float64]]
}
Expand All @@ -41,6 +50,10 @@ func (v normalNillableFloatArray) NillableFloatArray() ([]immutable.Option[float
return v.val, true
}

func (v normalNillableFloatArray) Equal(other NormalValue) bool {
return areNormalArraysOfNillablesEqual(v.val, other.NillableFloatArray)
}

type normalNillableStringArray struct {
baseArrayNormalValue[[]immutable.Option[string]]
}
Expand All @@ -49,6 +62,10 @@ func (v normalNillableStringArray) NillableStringArray() ([]immutable.Option[str
return v.val, true
}

func (v normalNillableStringArray) Equal(other NormalValue) bool {
return areNormalArraysOfNillablesEqual(v.val, other.NillableStringArray)
}

type normalNillableBytesArray struct {
baseArrayNormalValue[[]immutable.Option[[]byte]]
}
Expand All @@ -57,6 +74,13 @@ func (v normalNillableBytesArray) NillableBytesArray() ([]immutable.Option[[]byt
return v.val, true
}

func (v normalNillableBytesArray) Equal(other NormalValue) bool {
if otherVal, ok := other.NillableBytesArray(); ok {
return areArraysOfNillableBytesEqual(v.val, otherVal)
}
return false
}

type normalNillableTimeArray struct {
baseArrayNormalValue[[]immutable.Option[time.Time]]
}
Expand All @@ -65,6 +89,10 @@ func (v normalNillableTimeArray) NillableTimeArray() ([]immutable.Option[time.Ti
return v.val, true
}

func (v normalNillableTimeArray) Equal(other NormalValue) bool {
return areNormalArraysOfNillablesEqual(v.val, other.NillableTimeArray)
}

type normalNillableDocumentArray struct {
baseArrayNormalValue[[]immutable.Option[*Document]]
}
Expand All @@ -73,6 +101,10 @@ func (v normalNillableDocumentArray) NillableDocumentArray() ([]immutable.Option
return v.val, true
}

func (v normalNillableDocumentArray) Equal(other NormalValue) bool {
return areNormalArraysOfNillablesEqual(v.val, other.NillableDocumentArray)
}

// NewNormalNillableBoolNillableArray creates a new NormalValue that represents a
// `immutable.Option[[]immutable.Option[bool]]` value.
func NewNormalNillableBoolArray(val []immutable.Option[bool]) NormalValue {
Expand Down Expand Up @@ -140,3 +172,41 @@ func normalizeNillableCharsArr[R string | []byte, T string | []byte](val []immut
}
return arr
}

func areNormalArraysOfNillablesEqual[T comparable](
val []immutable.Option[T],
f func() ([]immutable.Option[T], bool),
) bool {
if otherVal, ok := f(); ok {
return areArraysOfNillablesEqual(val, otherVal)
}
return false
}

func areArraysOfNillablesEqual[T comparable](a, b []immutable.Option[T]) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}

func areArraysOfNillableBytesEqual(a, b []immutable.Option[[]byte]) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v.HasValue() && b[i].HasValue() {
if !bytes.Equal(v.Value(), b[i].Value()) {
return false
}
} else if v.HasValue() || b[i].HasValue() {
return false
}
}
return true
}
44 changes: 44 additions & 0 deletions client/normal_nillable_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ func (v normalBoolNillableArray) BoolNillableArray() (immutable.Option[[]bool],
return v.val, true
}

func (v normalBoolNillableArray) Equal(other NormalValue) bool {
return areOptionsArrEqual(v.val, other.BoolNillableArray)
}

type normalIntNillableArray struct {
baseNillableArrayNormalValue[[]int64]
}
Expand All @@ -60,6 +64,10 @@ func (v normalIntNillableArray) IntNillableArray() (immutable.Option[[]int64], b
return v.val, true
}

func (v normalIntNillableArray) Equal(other NormalValue) bool {
return areOptionsArrEqual(v.val, other.IntNillableArray)
}

type normalFloatNillableArray struct {
baseNillableArrayNormalValue[[]float64]
}
Expand All @@ -68,6 +76,10 @@ func (v normalFloatNillableArray) FloatNillableArray() (immutable.Option[[]float
return v.val, true
}

func (v normalFloatNillableArray) Equal(other NormalValue) bool {
return areOptionsArrEqual(v.val, other.FloatNillableArray)
}

type normalStringNillableArray struct {
baseNillableArrayNormalValue[[]string]
}
Expand All @@ -76,6 +88,10 @@ func (v normalStringNillableArray) StringNillableArray() (immutable.Option[[]str
return v.val, true
}

func (v normalStringNillableArray) Equal(other NormalValue) bool {
return areOptionsArrEqual(v.val, other.StringNillableArray)
}

type normalBytesNillableArray struct {
baseNillableArrayNormalValue[[][]byte]
}
Expand All @@ -84,6 +100,16 @@ func (v normalBytesNillableArray) BytesNillableArray() (immutable.Option[[][]byt
return v.val, true
}

func (v normalBytesNillableArray) Equal(other NormalValue) bool {
if otherVal, ok := other.BytesNillableArray(); ok {
if v.val.HasValue() && otherVal.HasValue() {
return are2DArraysEqual(v.val.Value(), otherVal.Value())
}
return !v.val.HasValue() && !otherVal.HasValue()
}
return false
}

type normalTimeNillableArray struct {
baseNillableArrayNormalValue[[]time.Time]
}
Expand All @@ -92,6 +118,10 @@ func (v normalTimeNillableArray) TimeNillableArray() (immutable.Option[[]time.Ti
return v.val, true
}

func (v normalTimeNillableArray) Equal(other NormalValue) bool {
return areOptionsArrEqual(v.val, other.TimeNillableArray)
}

type normalDocumentNillableArray struct {
baseNillableArrayNormalValue[[]*Document]
}
Expand All @@ -100,6 +130,10 @@ func (v normalDocumentNillableArray) DocumentNillableArray() (immutable.Option[[
return v.val, true
}

func (v normalDocumentNillableArray) Equal(other NormalValue) bool {
return areOptionsArrEqual(v.val, other.DocumentNillableArray)
}

// NewNormalNillableBoolArray creates a new NormalValue that represents a `immutable.Option[[]bool]` value.
func NewNormalBoolNillableArray(val immutable.Option[[]bool]) NormalValue {
return normalBoolNillableArray{newBaseNillableArrayNormalValue(val)}
Expand Down Expand Up @@ -150,3 +184,13 @@ func normalizeCharsNillableArr[R string | []byte, T string | []byte](val immutab
}
return immutable.None[[]R]()
}

func areOptionsArrEqual[T comparable](val immutable.Option[[]T], f func() (immutable.Option[[]T], bool)) bool {
if otherVal, ok := f(); ok {
if val.HasValue() && otherVal.HasValue() {
return areArraysEqual(val.Value(), otherVal.Value())
}
return !val.HasValue() && !otherVal.HasValue()
}
return false
}
Loading

0 comments on commit bc93bff

Please sign in to comment.