Skip to content

Commit

Permalink
in-memory cache support for geojson
Browse files Browse the repository at this point in the history
  • Loading branch information
akiyatomohiro committed Apr 18, 2024
1 parent 15875d5 commit 86b8e0a
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 4 deletions.
63 changes: 63 additions & 0 deletions server/internal/infrastructure/mongo/mongodoc/nlslayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mongodoc

import (
"errors"
"log"

"github.com/reearth/reearth/server/pkg/id"
"github.com/reearth/reearth/server/pkg/nlslayer"
Expand Down Expand Up @@ -536,6 +537,10 @@ func NewNLSLayerFeature(f nlslayer.Feature) NLSLayerFeatureDocument {
}

func NewNLSLayerGeometry(g nlslayer.Geometry) map[string]any {
if gMapFromRedis, ok := g.(map[string]any); ok {
return NewNLSLayerGeometryFromRedisMap(gMapFromRedis)
}

gMap := make(map[string]any)
switch g := g.(type) {
case *nlslayer.Point:
Expand All @@ -560,3 +565,61 @@ func NewNLSLayerGeometry(g nlslayer.Geometry) map[string]any {
}
return gMap
}

func NewNLSLayerGeometryFromRedisMap(redisMap map[string]any) map[string]any {
typeFields := []string{
"PointTypeField",
"LineStringTypeField",
"PolygonTypeField",
"MultiPolygonTypeField",
"GeometryCollectionTypeField",
}

var geometryType string
for _, field := range typeFields {
if typeVal, ok := redisMap[field]; ok {
geometryType = typeVal.(string)
break
}
}

if geometryType == "" {
log.Println("geometry type is missing")
return nil
}

gMap := make(map[string]any)
gMap["type"] = geometryType

if geometryType == "GeometryCollection" {
rawGeometries, ok := redisMap["GeometriesField"].([]any)
if !ok {
log.Println("invalid geometry collection data format")
return nil
}

gmapSlice := make([]map[string]any, 0, len(rawGeometries))
for _, rawGeometry := range rawGeometries {
geometry, ok := rawGeometry.(map[string]any)
if !ok {
log.Println("invalid geometry data format in collection")
continue
}

transformedGeometry := NewNLSLayerGeometryFromRedisMap(geometry)
if transformedGeometry != nil {
gmapSlice = append(gmapSlice, transformedGeometry)
}
}
gMap["geometries"] = gmapSlice
} else {
coords, ok := redisMap["CoordinatesField"]
if !ok {
log.Println("coordinates field is missing")
return nil
}
gMap["coordinates"] = coords
}

return gMap
}
89 changes: 89 additions & 0 deletions server/internal/infrastructure/mongo/mongodoc/nlslayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,95 @@ func TestNewNLSLayerGeometry(t *testing.T) {
args: nlslayer.Geometry(nil),
want: map[string]any{},
},
{
name: "New point from redis map",
args: map[string]any{
"PointTypeField": "Point",
"CoordinatesField": []any{1, 2},
},
want: map[string]any{
"type": "Point",
"coordinates": []any{1, 2},
},
},
{
name: "New line string from redis map",
args: map[string]any{
"LineStringTypeField": "LineString",
"CoordinatesField": [][]any{{1, 2}, {3, 4}},
},
want: map[string]any{
"type": "LineString",
"coordinates": [][]any{{1, 2}, {3, 4}},
},
},
{
name: "New polygon from redis map",
args: map[string]any{
"PolygonTypeField": "Polygon",
"CoordinatesField": [][][]any{{{1, 2}, {3, 4}, {5, 6}, {1, 2}}},
},
want: map[string]any{
"type": "Polygon",
"coordinates": [][][]any{{{1, 2}, {3, 4}, {5, 6}, {1, 2}}},
},
},
{
name: "New multi polygon from redis map",
args: map[string]any{
"MultiPolygonTypeField": "MultiPolygon",
"CoordinatesField": [][][][]any{{{{1, 2}, {3, 4}, {5, 6}, {1, 2}}}},
},
want: map[string]any{
"type": "MultiPolygon",
"coordinates": [][][][]any{{{{1, 2}, {3, 4}, {5, 6}, {1, 2}}}},
},
},
{
name: "New geometry collection from redis map",
args: map[string]any{
"GeometryCollectionTypeField": "GeometryCollection",
"GeometriesField": []any{
map[string]any{
"PointTypeField": "Point",
"CoordinatesField": []any{1, 2},
},
map[string]any{
"LineStringTypeField": "LineString",
"CoordinatesField": [][]any{{1, 2}, {3, 4}},
},
map[string]any{
"PolygonTypeField": "Polygon",
"CoordinatesField": [][][]any{{{1, 2}, {3, 4}, {5, 6}, {1, 2}}},
},
map[string]any{
"MultiPolygonTypeField": "MultiPolygon",
"CoordinatesField": [][][][]any{{{{1, 2}, {3, 4}, {5, 6}, {1, 2}}}},
},
},
},
want: map[string]any{
"type": "GeometryCollection",
"geometries": []map[string]any{
{
"type": "Point",
"coordinates": []any{1, 2},
},
{
"type": "LineString",
"coordinates": [][]any{{1, 2}, {3, 4}},
},
{
"type": "Polygon",
"coordinates": [][][]any{{{1, 2}, {3, 4}, {5, 6}, {1, 2}}},
},
{
"type": "MultiPolygon",
"coordinates": [][][][]any{{{{1, 2}, {3, 4}, {5, 6}, {1, 2}}}},
},
},
},
},
}

for _, tt := range tests {
Expand Down
72 changes: 68 additions & 4 deletions server/internal/usecase/interactor/nlslayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,11 +616,21 @@ func (i *NLSLayer) AddCustomProperties(ctx context.Context, inp interfaces.AddCu
}
}()

layer, err := i.nlslayerRepo.FindByID(ctx, inp.LayerID)
var layer nlslayer.NLSLayer
layerSimple, err := getFromCache[*nlslayer.NLSLayerSimple](ctx, i.redis, nlslayer.NLSLayerCacheKey(inp.LayerID))
if err != nil {
return nil, err
}

if layerSimple == nil {
layer, err = i.nlslayerRepo.FindByID(ctx, inp.LayerID)
if err != nil {
return nil, err
}
} else {
layer = layerSimple
}

if layer.Sketch() == nil {
featureCollection := nlslayer.NewFeatureCollection(
"FeatureCollection",
Expand All @@ -643,6 +653,12 @@ func (i *NLSLayer) AddCustomProperties(ctx context.Context, inp interfaces.AddCu
}

tx.Commit()

err = setToCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(layer.ID()), layer)
if err != nil {
return nil, err
}

return layer, nil
}

Expand All @@ -659,11 +675,21 @@ func (i *NLSLayer) AddGeoJSONFeature(ctx context.Context, inp interfaces.AddNLSL
}
}()

layer, err := i.nlslayerRepo.FindByID(ctx, inp.LayerID)
var layer nlslayer.NLSLayer
layerSimple, err := getFromCache[*nlslayer.NLSLayerSimple](ctx, i.redis, nlslayer.NLSLayerCacheKey(inp.LayerID))
if err != nil {
return nlslayer.Feature{}, err
}

if layerSimple == nil {
layer, err = i.nlslayerRepo.FindByID(ctx, inp.LayerID)
if err != nil {
return nlslayer.Feature{}, err
}
} else {
layer = layerSimple
}

geometry, err := nlslayer.NewGeometryFromMap(inp.Geometry)
if err != nil {
return nlslayer.Feature{}, err
Expand Down Expand Up @@ -704,6 +730,12 @@ func (i *NLSLayer) AddGeoJSONFeature(ctx context.Context, inp interfaces.AddNLSL
}

tx.Commit()

err = setToCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(layer.ID()), layer)
if err != nil {
return nlslayer.Feature{}, err
}

return *feature, nil
}

Expand All @@ -720,11 +752,21 @@ func (i *NLSLayer) UpdateGeoJSONFeature(ctx context.Context, inp interfaces.Upda
}
}()

layer, err := i.nlslayerRepo.FindByID(ctx, inp.LayerID)
var layer nlslayer.NLSLayer
layerSimple, err := getFromCache[*nlslayer.NLSLayerSimple](ctx, i.redis, nlslayer.NLSLayerCacheKey(inp.LayerID))
if err != nil {
return nlslayer.Feature{}, err
}

if layerSimple == nil {
layer, err = i.nlslayerRepo.FindByID(ctx, inp.LayerID)
if err != nil {
return nlslayer.Feature{}, err
}
} else {
layer = layerSimple
}

if layer.Sketch() == nil || layer.Sketch().FeatureCollection() == nil || layer.Sketch().FeatureCollection().Features() == nil || len(layer.Sketch().FeatureCollection().Features()) == 0 {
return nlslayer.Feature{}, interfaces.ErrFeatureNotFound
}
Expand Down Expand Up @@ -756,6 +798,12 @@ func (i *NLSLayer) UpdateGeoJSONFeature(ctx context.Context, inp interfaces.Upda
}

tx.Commit()

err = setToCache[nlslayer.NLSLayer](ctx, i.redis, nlslayer.NLSLayerCacheKey(layer.ID()), layer)
if err != nil {
return nlslayer.Feature{}, err
}

return updatedFeature, nil
}

Expand All @@ -772,11 +820,21 @@ func (i *NLSLayer) DeleteGeoJSONFeature(ctx context.Context, inp interfaces.Dele
}
}()

layer, err := i.nlslayerRepo.FindByID(ctx, inp.LayerID)
var layer nlslayer.NLSLayer
layerSimple, err := getFromCache[*nlslayer.NLSLayerSimple](ctx, i.redis, nlslayer.NLSLayerCacheKey(inp.LayerID))
if err != nil {
return id.FeatureID{}, err
}

if layerSimple == nil {
layer, err = i.nlslayerRepo.FindByID(ctx, inp.LayerID)
if err != nil {
return id.FeatureID{}, err
}
} else {
layer = layerSimple
}

if layer.Sketch() == nil || layer.Sketch().FeatureCollection() == nil || layer.Sketch().FeatureCollection().Features() == nil || len(layer.Sketch().FeatureCollection().Features()) == 0 {
return id.FeatureID{}, interfaces.ErrFeatureNotFound
}
Expand All @@ -792,5 +850,11 @@ func (i *NLSLayer) DeleteGeoJSONFeature(ctx context.Context, inp interfaces.Dele
}

tx.Commit()

err = deleteFromCache(ctx, i.redis, nlslayer.NLSLayerCacheKey(layer.ID()))
if err != nil {
return id.FeatureID{}, err
}

return inp.FeatureID, nil
}

0 comments on commit 86b8e0a

Please sign in to comment.