@Override
  public boolean put(K key, V value) {
    SpillableSetImpl<V> spillableSet = getHelper(key);

    if (spillableSet == null) {
      if (timeExtractor == null) {
        spillableSet =
            new SpillableSetImpl<>(
                bucket,
                keyValueSerdeManager.serializeDataKey(key, true).toByteArray(),
                store,
                valueSerde);
      } else {
        spillableSet =
            new SpillableSetImpl<>(
                keyValueSerdeManager.serializeDataKey(key, true).toByteArray(),
                store,
                valueSerde,
                new FixedTimeExtractor(timeExtractor.getTime(key)));
      }
      spillableSet.setup(context);
      cache.put(key, spillableSet);
    }
    return spillableSet.add(value);
  }
  private SpillableSetImpl<V> getHelper(@NotNull K key) {
    SpillableSetImpl<V> spillableSet = cache.get(key);

    if (spillableSet == null) {
      long keyTime = -1;
      Pair<Integer, V> meta;
      if (timeExtractor != null) {
        keyTime = timeExtractor.getTime(key);
      }
      meta = map.get(key);

      if (meta == null) {
        return null;
      }

      Slice keyPrefix = keyValueSerdeManager.serializeDataKey(key, false);
      if (timeExtractor != null) {
        spillableSet =
            new SpillableSetImpl<>(
                keyPrefix.toByteArray(), store, valueSerde, new FixedTimeExtractor(keyTime));
      } else {
        spillableSet = new SpillableSetImpl<>(bucket, keyPrefix.toByteArray(), store, valueSerde);
      }
      spillableSet.setSize(meta.getLeft());
      spillableSet.setHead(meta.getRight());
      spillableSet.setup(context);
    }

    cache.put(key, spillableSet);

    return spillableSet;
  }
 /**
  * Note that this always returns null because the set is no longer valid after this call
  *
  * @param key
  * @return null
  */
 @Override
 public Set<V> removeAll(@NotNull Object key) {
   SpillableSetImpl<V> spillableSet = getHelper((K) key);
   if (spillableSet != null) {
     cache.remove((K) key);
     map.put((K) key, new ImmutablePair<>(0, spillableSet.getHead()));
     spillableSet.clear();
     removedSets.add(spillableSet);
   }
   return null;
 }
  @Override
  public void endWindow() {
    for (K key : cache.getChangedKeys()) {

      SpillableSetImpl<V> spillableSet = cache.get(key);
      spillableSet.endWindow();

      map.put(key, new ImmutablePair<>(spillableSet.size(), spillableSet.getHead()));
    }

    for (SpillableSetImpl removedSet : removedSets) {
      removedSet.endWindow();
    }
    removedSets.clear();

    cache.endWindow();
    map.endWindow();

    keyValueSerdeManager.resetReadBuffer();
  }