Skip to content

Commit b329179

Browse files
authored
Merge pull request #53 from aliyun/feature/lazy_load
perf: lazy load fs meta info
2 parents 31c8cf0 + 6172bb3 commit b329179

File tree

4 files changed

+337
-23
lines changed

4 files changed

+337
-23
lines changed

api/api_feature_view.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,48 @@ func (a *FeatureViewApiService) ListFeatureViews(pagesize, pagenumber int32, pro
209209

210210
return localVarReturnValue, nil
211211
}
212+
213+
func (a *FeatureViewApiService) ListFeatureViewsByName(pagesize, pagenumber int32, projectId, featureViewName string) (ListFeatureViewsResponse, error) {
214+
var (
215+
localVarReturnValue ListFeatureViewsResponse
216+
)
217+
218+
request := paifeaturestore.ListFeatureViewsRequest{}
219+
request.SetPageSize(pagesize)
220+
request.SetPageNumber(pagenumber)
221+
request.SetProjectId(projectId)
222+
request.SetName(featureViewName)
223+
224+
response, err := a.client.ListFeatureViews(&a.client.instanceId, &request)
225+
if err != nil {
226+
return localVarReturnValue, nil
227+
}
228+
229+
localVarReturnValue.TotalCount = int(*response.Body.TotalCount)
230+
var featureViews []*FeatureView
231+
232+
for _, view := range response.Body.FeatureViews {
233+
if viewId, err := strconv.Atoi(*view.FeatureViewId); err == nil {
234+
featureView := FeatureView{
235+
FeatureViewId: viewId,
236+
Type: *view.Type,
237+
FeatureEntityName: *view.FeatureEntityName,
238+
ProjectName: *view.ProjectName,
239+
}
240+
if view.WriteToFeatureDB != nil {
241+
featureView.WriteToFeatureDB = *view.WriteToFeatureDB
242+
} else {
243+
featureView.WriteToFeatureDB = false
244+
}
245+
if id, err := strconv.Atoi(*view.ProjectId); err == nil {
246+
featureView.ProjectId = id
247+
}
248+
249+
featureViews = append(featureViews, &featureView)
250+
}
251+
}
252+
253+
localVarReturnValue.FeatureViews = featureViews
254+
255+
return localVarReturnValue, nil
256+
}

api/api_fs_model.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,40 @@ func (a *FsModelApiService) ListModels(pagesize, pagenumber int, projectId strin
179179
localVarReturnValue.Models = models
180180
return localVarReturnValue, nil
181181
}
182+
183+
func (a *FsModelApiService) ListModelsByName(pagesize, pagenumber int, projectId, modelName string) (ListModelsResponse, error) {
184+
var (
185+
localVarReturnValue ListModelsResponse
186+
)
187+
188+
request := paifeaturestore.ListModelFeaturesRequest{}
189+
request.SetPageSize(int32(pagesize))
190+
request.SetPageNumber(int32(pagenumber))
191+
request.SetProjectId(projectId)
192+
request.SetName(modelName)
193+
194+
response, err := a.client.ListModelFeatures(&a.client.instanceId, &request)
195+
if err != nil {
196+
return localVarReturnValue, err
197+
}
198+
199+
localVarReturnValue.TotalCount = int(*response.Body.TotalCount)
200+
var models []*Model
201+
for _, modelFeature := range response.Body.ModelFeatures {
202+
if id, err := strconv.Atoi(*modelFeature.ModelFeatureId); err == nil {
203+
model := Model{
204+
ModelId: id,
205+
Name: *modelFeature.Name,
206+
ProjectName: *modelFeature.ProjectName,
207+
}
208+
if id, err := strconv.Atoi(*modelFeature.ProjectId); err == nil {
209+
model.ProjectId = id
210+
}
211+
212+
models = append(models, &model)
213+
}
214+
}
215+
216+
localVarReturnValue.Models = models
217+
return localVarReturnValue, nil
218+
}

domain/project.go

Lines changed: 147 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package domain
22

33
import (
4+
"fmt"
5+
"strconv"
6+
"sync"
7+
48
"github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/api"
59
"github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/constants"
610
"github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/datasource/featuredb"
@@ -12,17 +16,18 @@ import (
1216
type Project struct {
1317
*api.Project
1418
OnlineStore OnlineStore
15-
FeatureViewMap map[string]FeatureView
19+
FeatureViewMap sync.Map
1620
FeatureEntityMap map[string]*FeatureEntity
17-
ModelMap map[string]*Model
21+
ModelMap sync.Map
22+
LabelTableMap sync.Map
23+
24+
apiClient *api.APIClient
1825
}
1926

2027
func NewProject(p *api.Project, isInitClient bool) *Project {
2128
project := Project{
2229
Project: p,
23-
FeatureViewMap: make(map[string]FeatureView),
2430
FeatureEntityMap: make(map[string]*FeatureEntity),
25-
ModelMap: make(map[string]*Model),
2631
}
2732

2833
switch p.OnlineDatasourceType {
@@ -77,17 +82,152 @@ func NewProject(p *api.Project, isInitClient bool) *Project {
7782
return &project
7883
}
7984

85+
func (p *Project) SetApiClient(apiClient *api.APIClient) {
86+
p.apiClient = apiClient
87+
}
88+
8089
func (p *Project) GetFeatureView(name string) FeatureView {
81-
return p.FeatureViewMap[name]
90+
if value, exists := p.FeatureViewMap.Load(name); exists {
91+
return value.(FeatureView)
92+
}
93+
if err := p.loadFeatureView(name); err != nil {
94+
return nil
95+
}
96+
if value, exists := p.FeatureViewMap.Load(name); exists {
97+
return value.(FeatureView)
98+
}
99+
return nil
82100
}
83101

84102
func (p *Project) GetFeatureEntity(name string) *FeatureEntity {
85103
return p.FeatureEntityMap[name]
86104
}
87105

106+
func (p *Project) GetLabelTable(labelTableId int) *LabelTable {
107+
if value, exists := p.LabelTableMap.Load(labelTableId); exists {
108+
return value.(*LabelTable)
109+
}
110+
if err := p.loadLabelTable(labelTableId); err != nil {
111+
return nil
112+
}
113+
if value, exists := p.LabelTableMap.Load(labelTableId); exists {
114+
return value.(*LabelTable)
115+
}
116+
return nil
117+
}
118+
88119
func (p *Project) GetModel(name string) *Model {
89-
return p.ModelMap[name]
120+
if value, exists := p.ModelMap.Load(name); exists {
121+
return value.(*Model)
122+
}
123+
if err := p.loadModelFeature(name); err != nil {
124+
return nil
125+
}
126+
if value, exists := p.ModelMap.Load(name); exists {
127+
return value.(*Model)
128+
}
129+
return nil
90130
}
91131
func (p *Project) GetModelFeature(name string) *Model {
92-
return p.ModelMap[name]
132+
if value, exists := p.ModelMap.Load(name); exists {
133+
return value.(*Model)
134+
}
135+
if err := p.loadModelFeature(name); err != nil {
136+
return nil
137+
}
138+
if value, exists := p.ModelMap.Load(name); exists {
139+
return value.(*Model)
140+
}
141+
return nil
142+
}
143+
144+
func (p *Project) loadFeatureView(featureViewName string) error {
145+
pageNumber := 1
146+
pageSize := 100
147+
for {
148+
listFeatureViews, err := p.apiClient.FeatureViewApi.ListFeatureViewsByName(int32(pageSize), int32(pageNumber), strconv.Itoa(p.ProjectId), featureViewName)
149+
if err != nil {
150+
fmt.Printf("list feature views error, err=%v", err)
151+
return err
152+
}
153+
for _, view := range listFeatureViews.FeatureViews {
154+
getFeatureViewResponse, err := p.apiClient.FeatureViewApi.GetFeatureViewByID(strconv.Itoa(int(view.FeatureViewId)))
155+
if err != nil {
156+
fmt.Printf("get feature view error, err=%v", err)
157+
return err
158+
}
159+
featureView := getFeatureViewResponse.FeatureView
160+
if featureView.RegisterDatasourceId > 0 {
161+
getDataSourceResponse, err := p.apiClient.DatasourceApi.DatasourceDatasourceIdGet(featureView.RegisterDatasourceId, 0, "")
162+
if err != nil {
163+
fmt.Printf("get datasource error, err=%v", err)
164+
return err
165+
}
166+
featureView.RegisterDataSource = getDataSourceResponse.Datasource
167+
}
168+
169+
entity, exist := p.FeatureEntityMap[featureView.FeatureEntityName]
170+
if !exist {
171+
fmt.Printf("feature entity not exist, name=%s", featureView.FeatureEntityName)
172+
return fmt.Errorf("feature entity not exist, name=%s", featureView.FeatureEntityName)
173+
}
174+
featureViewDomain := NewFeatureView(featureView, p, entity)
175+
p.FeatureViewMap.Store(featureView.Name, featureViewDomain)
176+
}
177+
178+
if len(listFeatureViews.FeatureViews) == 0 || pageSize*pageNumber > listFeatureViews.TotalCount {
179+
break
180+
}
181+
182+
pageNumber++
183+
}
184+
185+
return nil
186+
}
187+
188+
func (p *Project) loadLabelTable(labelTableId int) error {
189+
getLabelTableResponse, err := p.apiClient.LabelTableApi.GetLabelTableByID(strconv.Itoa(labelTableId))
190+
if err != nil {
191+
fmt.Printf("get label table error, err=%v", err)
192+
return err
193+
}
194+
labelTableDomain := NewLabelTable(getLabelTableResponse.LabelTable)
195+
p.LabelTableMap.Store(labelTableId, labelTableDomain)
196+
197+
return nil
198+
}
199+
200+
func (p *Project) loadModelFeature(modelFeatureName string) error {
201+
pageNumber := 1
202+
pageSize := 100
203+
for {
204+
listModelFeatures, err := p.apiClient.FsModelApi.ListModelsByName(pageSize, pageNumber, strconv.Itoa(p.ProjectId), modelFeatureName)
205+
if err != nil {
206+
fmt.Printf("list model features error, err=%v", err)
207+
return err
208+
}
209+
for _, m := range listModelFeatures.Models {
210+
getModelFeatureResponse, err := p.apiClient.FsModelApi.GetModelByID(strconv.Itoa(m.ModelId))
211+
if err != nil {
212+
fmt.Printf("get model feature error, err=%v", err)
213+
return err
214+
}
215+
model := getModelFeatureResponse.Model
216+
labelTableDomain := p.GetLabelTable(model.LabelTableId)
217+
if labelTableDomain == nil {
218+
fmt.Printf("label table not exist, id=%d", model.LabelTableId)
219+
return fmt.Errorf("label table not exist, id=%d", model.LabelTableId)
220+
}
221+
modelDomain := NewModel(model, p, labelTableDomain)
222+
p.ModelMap.Store(model.Name, modelDomain)
223+
}
224+
225+
if len(listModelFeatures.Models) == 0 || pageSize*pageNumber > listModelFeatures.TotalCount {
226+
break
227+
}
228+
229+
pageNumber++
230+
}
231+
232+
return nil
93233
}

0 commit comments

Comments
 (0)