Home > Back-end >  How to avoid nested map allocations in my data structure?
How to avoid nested map allocations in my data structure?

Time:06-30

I have a below struct where I have a nested map for CustomersIndex which allocates bunch of internal maps causing memory increase. I profiled it so I noticed this. I am trying to see if there is any way to redesign my CustomersIndex data structure which doesn't uses nested map?

const (
    departmentsKey = "departments"
)

type CustomerManifest struct {
    Customers      []definitions.Customer
    CustomersIndex map[int]map[int]definitions.Customer
}

This is the way it is being populated here in my below code:

func updateData(mdmCache *mdm.Cache) map[string]interface{} {
    memCache := mdmCache.MemCache()

    var customers []definitions.Customer
    var customersIndex = map[int]map[int]definitions.Customer{}

    for _, r := range memCache.Customer {
        customer := definitions.Customer{
            Id:           int(r.Id),
            SetId:        int(r.DepartmentSetId),
        }

        customers = append(customers, customer)
        _, yes := customersIndex[customer.SetId]
        if !yes {
            customersIndex[customer.SetId] = make(map[int]definitions.Customer)
        }
        customersIndex[customer.SetId][customer.Id] = customer
    }

    return map[string]interface{}{
        departmentsKey: &CustomerManifest{Customers: customers, CustomersIndex: customersIndex},
    }
}

And this is the way I am getting my CustomersIndex nested map.

func (c *Client) GetCustomerIndex() map[int]map[int]definitions.Customer {
    c.mutex.RLock()
    defer c.mutex.RUnlock()
    customersIndex := c.data[departmentsKey].(*CustomerManifest).CustomersIndex
    return customersIndex
}

Is there any way to design my CustomersIndex in a way where I don't have to use nested map?

CodePudding user response:

You don't need to allocate a map until you put values in it.

type CustomerManifest struct {
    Customers      []definitions.Customer
    CustomersIndex map[int]map[int]definitions.Customer
}

func (m *CustomerManifest) AddCustomerDefinition(x, y int, customer definitions.Customer) {
    // Get the existing map, if exists.
    innerMap := m.CustomersIndex[x]
    // If it doesn't exist, allocate it.
    if innerMap == nil {
        innerMap = make(map[int]definitions.Customer)
        m.CustomersIndex[x] = innerMap
    }
    // Add the value to the inner map, which now exists.
    innerMap[y] = customer
}
  • Related