From e054bfc99668d519bf6f7253b4a56cea8b4855c9 Mon Sep 17 00:00:00 2001 From: Ilja Neumann Date: Thu, 1 Oct 2020 12:33:23 +0200 Subject: [PATCH] WIP --- accounts/pkg/index/index.go | 63 ++++++++++++--------------- accounts/pkg/index/map.go | 26 +++++++---- accounts/pkg/index/non_unique.go | 4 +- accounts/pkg/index/non_unique_test.go | 6 +-- accounts/pkg/index/reflect.go | 9 ++++ accounts/pkg/index/unique_test.go | 2 +- 6 files changed, 59 insertions(+), 51 deletions(-) diff --git a/accounts/pkg/index/index.go b/accounts/pkg/index/index.go index ca5162938..85d801083 100644 --- a/accounts/pkg/index/index.go +++ b/accounts/pkg/index/index.go @@ -18,9 +18,9 @@ type Config struct { Log zerolog.Logger } -// Type can be implemented to create new index-strategies. See Unique for example. +// IndexType can be implemented to create new index-strategies. See Unique for example. // Each index implementation is bound to one data-column (IndexBy) and a data-type (TypeName) -type Type interface { +type IndexType interface { Init() error Lookup(v string) ([]string, error) Add(id, v string) (string, error) @@ -39,63 +39,52 @@ func NewIndex(cfg *Config) *Index { } } -func (man Index) AddUniqueIndex(typeName, indexBy, entityDirName string) error { - fullDataPath := path.Join(man.config.DataDir, entityDirName) - indexPath := path.Join(man.config.DataDir, man.config.IndexRootDirName) + +func (i Index) AddUniqueIndex(t interface{}, indexBy, pkName, entityDirName string) error { + typeName := getTypeFQN(t) + fullDataPath := path.Join(i.config.DataDir, entityDirName) + indexPath := path.Join(i.config.DataDir, i.config.IndexRootDirName) idx := NewUniqueIndex(typeName, indexBy, fullDataPath, indexPath) - man.indices.addIndex(idx) + i.indices.addIndex(typeName, pkName, idx) return idx.Init() } -func (man Index) AddNormalIndex(typeName, indexBy, entityDirName string) error { - fullDataPath := path.Join(man.config.DataDir, entityDirName) - indexPath := path.Join(man.config.DataDir, man.config.IndexRootDirName) +func (i Index) AddNonUniqueIndex(t interface{}, indexBy, pkName, entityDirName string) error { + typeName := getTypeFQN(t) + fullDataPath := path.Join(i.config.DataDir, entityDirName) + indexPath := path.Join(i.config.DataDir, i.config.IndexRootDirName) - idx := NewNormalIndex(typeName, indexBy, fullDataPath, indexPath) - man.indices.addIndex(idx) + idx := NewNonUniqueIndex(typeName, indexBy, fullDataPath, indexPath) + i.indices.addIndex(typeName, pkName, idx) return idx.Init() } -func (man Index) AddIndex(idx Type) error { - man.indices.addIndex(idx) - return idx.Init() -} // Add a new entry to the index -func (man Index) Add(primaryKey string, entity interface{}) error { - t, err := getType(entity) - if err != nil { - return err +func (i Index) Add(t interface{}) error { + typeName := getTypeFQN(t) + + val, ok := i.indices[typeName] + if ok { + } - typeName := t.Type().Name() - if typeIndices, ok := man.indices[typeName]; ok { - for _, fieldIndices := range typeIndices { - for k := range fieldIndices { - curIdx := fieldIndices[k] - idxBy := curIdx.IndexBy() - val := valueOf(entity, idxBy) - _, err := curIdx.Add(primaryKey, val) - if err != nil { - return err - } - } - } - } return nil + + } // Find a entry by type,field and value. // // Find a User type by email // man.Find("User", "Email", "foo@example.com") -func (man Index) Find(typeName, key, value string) (pk string, err error) { +func (i Index) Find(typeName, key, value string) (pk string, err error) { var res = []string{} - if indices, ok := man.indices[typeName][key]; ok { + if indices, ok := i.indices[typeName][key]; ok { for _, idx := range indices { if res, err = idx.Lookup(value); IsNotFoundErr(err) { continue @@ -114,7 +103,9 @@ func (man Index) Find(typeName, key, value string) (pk string, err error) { return path.Base(res[0]), err } -func (man Index) Delete(typeName, pk string) error { +func (i Index) Delete(typeName, pk string) error { return nil } + + */ diff --git a/accounts/pkg/index/map.go b/accounts/pkg/index/map.go index 2d5f62444..5a63f2fd7 100644 --- a/accounts/pkg/index/map.go +++ b/accounts/pkg/index/map.go @@ -1,16 +1,24 @@ package index // indexMap stores the index layout at runtime. -type indexMap map[tName]map[indexByKey][]Type +type indexMap map[tName]typeMapping type tName = string -type indexByKey = string -func (m indexMap) addIndex(idx Type) { - typeName, indexBy := idx.TypeName(), idx.IndexBy() - if _, ok := m[typeName]; !ok { - m[typeName] = map[indexByKey][]Type{} - } - - m[typeName][indexBy] = append(m[typeName][indexBy], idx) +type typeMapping struct { + pKFieldName string + indicesByField map[string][]IndexType +} + +func (m indexMap) addIndex(typeName string, pkName string, idx IndexType) { + if val, ok := m[typeName]; ok { + val.indicesByField[idx.IndexBy()] = append(val.indicesByField[idx.IndexBy()], idx) + return + } + m[typeName] = typeMapping{ + pKFieldName: pkName, + indicesByField: map[string][]IndexType{ + pkName: {idx}, + }, + } } diff --git a/accounts/pkg/index/non_unique.go b/accounts/pkg/index/non_unique.go index 7d504f9c7..7046c4ddd 100644 --- a/accounts/pkg/index/non_unique.go +++ b/accounts/pkg/index/non_unique.go @@ -27,9 +27,9 @@ type NonUniqueIndex struct { indexRootDir string } -// NewNormalIndex instantiates a new NonUniqueIndex instance. Init() should be +// NewNonUniqueIndex instantiates a new NonUniqueIndex instance. Init() should be // called afterward to ensure correct on-disk structure. -func NewNormalIndex(typeName, indexBy, filesDir, indexBaseDir string) NonUniqueIndex { +func NewNonUniqueIndex(typeName, indexBy, filesDir, indexBaseDir string) NonUniqueIndex { return NonUniqueIndex{ indexBy: indexBy, typeName: typeName, diff --git a/accounts/pkg/index/non_unique_test.go b/accounts/pkg/index/non_unique_test.go index 17a6c3340..473604d01 100644 --- a/accounts/pkg/index/non_unique_test.go +++ b/accounts/pkg/index/non_unique_test.go @@ -55,7 +55,7 @@ func TestNonUniqueIndexInit(t *testing.T) { indexRootDir := path.Join(dataDir, "index.disk") filesDir := path.Join(dataDir, "users") - uniq := NewNormalIndex("User", "DisplayName", filesDir, indexRootDir) + uniq := NewNonUniqueIndex("User", "DisplayName", filesDir, indexRootDir) assert.Error(t, uniq.Init(), "Init should return an error about missing files-dir") if err := os.Mkdir(filesDir, 0777); err != nil { @@ -87,9 +87,9 @@ func TestNonUniqueIndexSearch(t *testing.T) { _ = os.RemoveAll(dataPath) } -func getNonUniqueIdxSut(t *testing.T) (sut Type, dataPath string) { +func getNonUniqueIdxSut(t *testing.T) (sut IndexType, dataPath string) { dataPath = writeIndexTestData(t, testData, "Id") - sut = NewNormalIndex("Pet", "Color", path.Join(dataPath, "pets"), path.Join(dataPath, "index.disk")) + sut = NewNonUniqueIndex("Pet", "Color", path.Join(dataPath, "pets"), path.Join(dataPath, "index.disk")) err := sut.Init() if err != nil { t.Fatal(err) diff --git a/accounts/pkg/index/reflect.go b/accounts/pkg/index/reflect.go index 0cdc28232..3775c2caf 100644 --- a/accounts/pkg/index/reflect.go +++ b/accounts/pkg/index/reflect.go @@ -2,7 +2,9 @@ package index import ( "errors" + "path" "reflect" + "strings" ) func getType(v interface{}) (reflect.Value, error) { @@ -17,6 +19,13 @@ func getType(v interface{}) (reflect.Value, error) { return rv, nil } +func getTypeFQN(t interface{}) string { + typ, _ := getType(t) + typeName := path.Join(typ.Type().PkgPath(), typ.Type().Name()) + typeName = strings.ReplaceAll(typeName, "/", ".") + return typeName +} + func valueOf(v interface{}, field string) string { r := reflect.ValueOf(v) f := reflect.Indirect(r).FieldByName(field) diff --git a/accounts/pkg/index/unique_test.go b/accounts/pkg/index/unique_test.go index 958f8c3a8..f9b4eb0e2 100644 --- a/accounts/pkg/index/unique_test.go +++ b/accounts/pkg/index/unique_test.go @@ -112,7 +112,7 @@ func TestErrors(t *testing.T) { assert.True(t, IsNotFoundErr(¬FoundErr{})) } -func getUniqueIdxSut(t *testing.T) (sut Type, dataPath string) { +func getUniqueIdxSut(t *testing.T) (sut IndexType, dataPath string) { dataPath = writeIndexTestData(t, testData, "Id") sut = NewUniqueIndex("User", "Email", path.Join(dataPath, "users"), path.Join(dataPath, "index.disk")) err := sut.Init()