private synchronized Int2ObjectMap<int[]> getOrLoadStorage() {
    Int2ObjectMap<int[]> cachedElements;
    if (cache != null && (cachedElements = cache.get()) != null) {
      hitCount.incrementAndGet();
      return cachedElements;
    }

    missCount.incrementAndGet();
    cachedElements = new Int2ObjectOpenHashMap<int[]>();
    FileInputStream in = null;
    try {
      file.createNewFile();
      in = new FileInputStream(file);
      // in.skip(startPos);
      
      for (Entry metaEntry : cacheMetaData.int2IntEntrySet()) {
        int keyId = metaEntry.getIntKey();
        int valueSize = metaEntry.getIntValue();
        
        int[] values = new int[valueSize];
        
        for (int i = 0; i < valueSize; i++) {
          int elementId = EncodingUtils.readInt(in);
          values[i] = elementId;
        }
        
        cachedElements.put(keyId, values);
      }
      
      
    } catch (IOException e) {
      throw new RuntimeException(e);
    } finally {
      if (in != null)
        try {
          in.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
    }

    this.cache = new SoftReference<Int2ObjectMap<int[]>>(cachedElements);

    return cachedElements;
  }