0

I'm working in an ecommerce product. This ecommerce has many online stores on many locations. For each category, it has different id in different store. The problem is now we want to mapping categories between stores of the same kind of product.

We have a json stored in database which contains a country mapping:

[
  {
    "sg": 4,
    "jp": 128,
    "ph": 4,
    "hk": 4,
    "th": null
  },
  ...
]

So this means the category id 4 in Singapore is 128 in the Japan. We are actually using a structure like this to map categories across countries.

I have this interface to achieve this:

public interface CategoryMapper {
    int getCategory(String sourceCountry, String destinationCountry, int categoryId);
}

I want to optimize for reading speed. How should I implement to achieve this?

I have 2 options below

  1. Using java hash map to store as key/value
  2. Using cache framework and store as key/value

Thanks

Barcelona
  • 2,122
  • 4
  • 21
  • 42

2 Answers2

1

One way to solve this problem is to create a 2-way mapping like as the following, there is no redundancy since we're not storing objects, as small strings are immutable, for example, the word "Electronic" is stored only once in memory.

Try Online

class ProductCategoryMap
{
    Map<String,Set<String>> prodMap;
    Map<String,String> codeMap;
    Map<String,Integer> catMap;

    public ProductCategoryMap()
    {
        prodMap = new HashMap<>();
        codeMap = new HashMap<>();
        catMap = new HashMap<>();
    }

    public void put(String category, String region, int code)
    {
        if(!prodMap.containsKey(category))
        {
            prodMap.put(category, new TreeSet<>());
        }
        prodMap.get(category).add(region);

        catMap.put(category+region, code);
        codeMap.put(region+code, category);
    }

    public String getCategory(String country, int catId)
    {
        return codeMap.get(country+catId);
    }

    public int getCategoryId(String category, String country)
    {
        return catMap.get(category+country);
    }

    public int getDestCatId(String srcCountry, String destCountry, int srcCatId)
    {
        String category = getCategory(srcCountry, srcCatId);
        return getCategoryId(category, destCountry);
    }

    public TreeSet<String> getAvailability(String category)
    {
        return prodMap.get(category);
    }
}
Khaled.K
  • 5,828
  • 1
  • 33
  • 51
0

You can use a HashMap of HashMaps to do that as follows:

Map<String, Map<String, Integer>> map = new HashMap<String, Map<String, Integer>>();

Where the first key (the key of the outer map) is the category name (e.g. Electronics) and the second key (the key of the inner maps) is the location name. This way you can efficiently get any id with 2 HashMap accesses. You can limit your HashMap size making it an LRU (or any other policy) cache by using LinkedHashMap as described in this SO post. Other than that, you can use a Java caching framework like EHCache or OSCache.

zuckermanori
  • 1,675
  • 5
  • 22
  • 31