mirror of
https://github.com/openobserve/goflow2.git
synced 2025-10-23 07:11:57 +00:00
decoders: improve BasicTemplateSystem (#233)
* Use write lock when removing template Since template removal modifies the template set map, it should be done while holding a write lock, instead of a read lock. * Optimize BasicTemplateSystem The BasicTemplateSystem that comes with the library uses a 3-level map to hold template information to avoid templateId and obsDomainId collision between multiple protocols and hosts. However, the same can be done by using a single map with a 64-bit key consisting of version, templateId and obsDomainId. This greatly simplifies the code and reduces the number of map lookups from 3 to 1 per call to GetTemplate. Co-authored-by: Matheus Castanho <matheus.castanho@dcc.ufmg.br>
This commit is contained in:
@@ -9,7 +9,11 @@ var (
|
|||||||
ErrorTemplateNotFound = fmt.Errorf("Error template not found")
|
ErrorTemplateNotFound = fmt.Errorf("Error template not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
type FlowBaseTemplateSet map[uint16]map[uint32]map[uint16]interface{}
|
type FlowBaseTemplateSet map[uint64]interface{}
|
||||||
|
|
||||||
|
func templateKey(version uint16, obsDomainId uint32, templateId uint16) uint64 {
|
||||||
|
return (uint64(version) << 48) | (uint64(obsDomainId) << 16) | uint64(templateId)
|
||||||
|
}
|
||||||
|
|
||||||
// Store interface that allows storing, removing and retrieving template data
|
// Store interface that allows storing, removing and retrieving template data
|
||||||
type NetFlowTemplateSystem interface {
|
type NetFlowTemplateSystem interface {
|
||||||
@@ -18,7 +22,7 @@ type NetFlowTemplateSystem interface {
|
|||||||
AddTemplate(version uint16, obsDomainId uint32, templateId uint16, template interface{}) error
|
AddTemplate(version uint16, obsDomainId uint32, templateId uint16, template interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *BasicTemplateSystem) GetTemplates() map[uint16]map[uint32]map[uint16]interface{} {
|
func (ts *BasicTemplateSystem) GetTemplates() FlowBaseTemplateSet {
|
||||||
ts.templateslock.RLock()
|
ts.templateslock.RLock()
|
||||||
tmp := ts.templates
|
tmp := ts.templates
|
||||||
ts.templateslock.RUnlock()
|
ts.templateslock.RUnlock()
|
||||||
@@ -28,14 +32,7 @@ func (ts *BasicTemplateSystem) GetTemplates() map[uint16]map[uint32]map[uint16]i
|
|||||||
func (ts *BasicTemplateSystem) AddTemplate(version uint16, obsDomainId uint32, templateId uint16, template interface{}) error {
|
func (ts *BasicTemplateSystem) AddTemplate(version uint16, obsDomainId uint32, templateId uint16, template interface{}) error {
|
||||||
ts.templateslock.Lock()
|
ts.templateslock.Lock()
|
||||||
defer ts.templateslock.Unlock()
|
defer ts.templateslock.Unlock()
|
||||||
_, exists := ts.templates[version]
|
|
||||||
if !exists {
|
|
||||||
ts.templates[version] = make(map[uint32]map[uint16]interface{})
|
|
||||||
}
|
|
||||||
_, exists = ts.templates[version][obsDomainId]
|
|
||||||
if !exists {
|
|
||||||
ts.templates[version][obsDomainId] = make(map[uint16]interface{})
|
|
||||||
}
|
|
||||||
/*var templateId uint16
|
/*var templateId uint16
|
||||||
switch templateIdConv := template.(type) {
|
switch templateIdConv := template.(type) {
|
||||||
case IPFIXOptionsTemplateRecord:
|
case IPFIXOptionsTemplateRecord:
|
||||||
@@ -45,41 +42,29 @@ func (ts *BasicTemplateSystem) AddTemplate(version uint16, obsDomainId uint32, t
|
|||||||
case TemplateRecord:
|
case TemplateRecord:
|
||||||
templateId = templateIdConv.TemplateId
|
templateId = templateIdConv.TemplateId
|
||||||
}*/
|
}*/
|
||||||
ts.templates[version][obsDomainId][templateId] = template
|
key := templateKey(version, obsDomainId, templateId)
|
||||||
|
ts.templates[key] = template
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *BasicTemplateSystem) GetTemplate(version uint16, obsDomainId uint32, templateId uint16) (interface{}, error) {
|
func (ts *BasicTemplateSystem) GetTemplate(version uint16, obsDomainId uint32, templateId uint16) (interface{}, error) {
|
||||||
ts.templateslock.RLock()
|
ts.templateslock.RLock()
|
||||||
defer ts.templateslock.RUnlock()
|
defer ts.templateslock.RUnlock()
|
||||||
if templatesVersion, ok := ts.templates[version]; ok {
|
key := templateKey(version, obsDomainId, templateId)
|
||||||
if templatesObsDom, ok := templatesVersion[obsDomainId]; ok {
|
if template, ok := ts.templates[key]; ok {
|
||||||
if template, ok := templatesObsDom[templateId]; ok {
|
return template, nil
|
||||||
return template, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, ErrorTemplateNotFound
|
return nil, ErrorTemplateNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *BasicTemplateSystem) RemoveTemplate(version uint16, obsDomainId uint32, templateId uint16) (interface{}, error) {
|
func (ts *BasicTemplateSystem) RemoveTemplate(version uint16, obsDomainId uint32, templateId uint16) (interface{}, error) {
|
||||||
ts.templateslock.RLock()
|
ts.templateslock.Lock()
|
||||||
defer ts.templateslock.RUnlock()
|
defer ts.templateslock.Unlock()
|
||||||
if templatesVersion, ok := ts.templates[version]; ok {
|
|
||||||
if templatesObsDom, ok := templatesVersion[obsDomainId]; ok {
|
|
||||||
if template, ok := templatesObsDom[templateId]; ok {
|
|
||||||
|
|
||||||
delete(templatesObsDom, templateId)
|
key := templateKey(version, obsDomainId, templateId)
|
||||||
if len(templatesObsDom) == 0 {
|
if template, ok := ts.templates[key]; ok {
|
||||||
delete(templatesVersion, obsDomainId)
|
delete(ts.templates, key)
|
||||||
if len(templatesVersion) == 0 {
|
return template, nil
|
||||||
delete(ts.templates, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return template, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, ErrorTemplateNotFound
|
return nil, ErrorTemplateNotFound
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user