Java Code Examples for java.util.SortedSet#contains()

The following examples show how to use java.util.SortedSet#contains() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DataJanitorState.java    From phoenix-tephra with Apache License 2.0 6 votes vote down vote up
/**
 * Return regions that were recorded as empty after the given time.
 *
 * @param time time in milliseconds
 * @param includeRegions If not null, the returned set will be an intersection of the includeRegions set
 *                       and the empty regions after the given time
 */
public SortedSet<byte[]> getEmptyRegionsAfterTime(long time, @Nullable SortedSet<byte[]> includeRegions)
  throws IOException {
  SortedSet<byte[]> emptyRegions = new TreeSet<>(Bytes.BYTES_COMPARATOR);
  try (Table stateTable = stateTableSupplier.get()) {
    Scan scan = new Scan(makeEmptyRegionTimeKey(Bytes.toBytes(time + 1), EMPTY_BYTE_ARRAY),
                         EMPTY_REGION_TIME_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, EMPTY_REGION_TIME_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] emptyRegion = getEmptyRegionFromKey(next.getRow());
        if (includeRegions == null || includeRegions.contains(emptyRegion)) {
          emptyRegions.add(emptyRegion);
        }
      }
    }
  }
  return Collections.unmodifiableSortedSet(emptyRegions);
}
 
Example 2
Source File: NamespaceIsolationPolicyImplTest.java    From pulsar with Apache License 2.0 6 votes vote down vote up
@Test
public void testGetAvailablePrimaryBrokers() throws Exception {
    NamespaceIsolationPolicyImpl defaultPolicy = this.getDefaultPolicy();
    SortedSet<BrokerStatus> brokerStatus = new TreeSet<>();
    SortedSet<BrokerStatus> expectedAvailablePrimaries = new TreeSet<>();
    for (int i = 0; i < 10; i++) {
        BrokerStatus status = new BrokerStatus(String.format("prod1-broker%d.messaging.use.example.com", i),
                i % 2 == 0, i * 10);
        brokerStatus.add(status);
        if (i % 2 == 0) {
            expectedAvailablePrimaries.add(status);
        }
    }

    SortedSet<BrokerStatus> availablePrimaries = defaultPolicy.getAvailablePrimaryBrokers(brokerStatus);
    assertEquals(expectedAvailablePrimaries.size(), availablePrimaries.size());
    for (BrokerStatus bs : availablePrimaries) {
        if (!expectedAvailablePrimaries.contains(bs)) {
            fail("Should not happen");
        }
    }

}
 
Example 3
Source File: DataJanitorState.java    From phoenix-tephra with Apache License 2.0 6 votes vote down vote up
/**
 * Delete prune upper bounds for the regions that are not in the given exclude set, and the
 * prune upper bound is less than the given value.
 * After the invalid list is pruned up to deletionPruneUpperBound, we do not need entries for regions that have
 * prune upper bound less than deletionPruneUpperBound. We however limit the deletion to only regions that are
 * no longer in existence (due to deletion, etc.), to avoid update/delete race conditions.
 *
 * @param deletionPruneUpperBound prune upper bound below which regions will be deleted
 * @param excludeRegions set of regions that should not be deleted
 * @throws IOException when not able to delete data in HBase
 */
public void deletePruneUpperBounds(long deletionPruneUpperBound, SortedSet<byte[]> excludeRegions)
  throws IOException {
  try (Table stateTable = stateTableSupplier.get()) {
    byte[] startRow = makeRegionKey(EMPTY_BYTE_ARRAY);
    Scan scan = new Scan(startRow, REGION_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, PRUNE_UPPER_BOUND_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] region = getRegionFromKey(next.getRow());
        if (!excludeRegions.contains(region)) {
          byte[] timeBytes = next.getValue(FAMILY, PRUNE_UPPER_BOUND_COL);
          if (timeBytes != null) {
            long pruneUpperBoundRegion = Bytes.toLong(timeBytes);
            if (pruneUpperBoundRegion < deletionPruneUpperBound) {
              stateTable.delete(new Delete(next.getRow()));
            }
          }
        }
      }
    }
  }
}
 
Example 4
Source File: DataJanitorState.java    From phoenix-tephra with Apache License 2.0 6 votes vote down vote up
/**
 * Delete prune upper bounds for the regions that are not in the given exclude set, and the
 * prune upper bound is less than the given value.
 * After the invalid list is pruned up to deletionPruneUpperBound, we do not need entries for regions that have
 * prune upper bound less than deletionPruneUpperBound. We however limit the deletion to only regions that are
 * no longer in existence (due to deletion, etc.), to avoid update/delete race conditions.
 *
 * @param deletionPruneUpperBound prune upper bound below which regions will be deleted
 * @param excludeRegions set of regions that should not be deleted
 * @throws IOException when not able to delete data in HBase
 */
public void deletePruneUpperBounds(long deletionPruneUpperBound, SortedSet<byte[]> excludeRegions)
  throws IOException {
  try (Table stateTable = stateTableSupplier.get()) {
    byte[] startRow = makeRegionKey(EMPTY_BYTE_ARRAY);
    Scan scan = new Scan(startRow, REGION_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, PRUNE_UPPER_BOUND_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] region = getRegionFromKey(next.getRow());
        if (!excludeRegions.contains(region)) {
          byte[] timeBytes = next.getValue(FAMILY, PRUNE_UPPER_BOUND_COL);
          if (timeBytes != null) {
            long pruneUpperBoundRegion = Bytes.toLong(timeBytes);
            if (pruneUpperBoundRegion < deletionPruneUpperBound) {
              stateTable.delete(new Delete(next.getRow()));
            }
          }
        }
      }
    }
  }
}
 
Example 5
Source File: DataJanitorState.java    From phoenix-tephra with Apache License 2.0 6 votes vote down vote up
/**
 * Return regions that were recorded as empty after the given time.
 *
 * @param time time in milliseconds
 * @param includeRegions If not null, the returned set will be an intersection of the includeRegions set
 *                       and the empty regions after the given time
 */
public SortedSet<byte[]> getEmptyRegionsAfterTime(long time, @Nullable SortedSet<byte[]> includeRegions)
  throws IOException {
  SortedSet<byte[]> emptyRegions = new TreeSet<>(Bytes.BYTES_COMPARATOR);
  try (HTableInterface stateTable = stateTableSupplier.get()) {
    Scan scan = new Scan(makeEmptyRegionTimeKey(Bytes.toBytes(time + 1), EMPTY_BYTE_ARRAY),
                         EMPTY_REGION_TIME_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, EMPTY_REGION_TIME_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] emptyRegion = getEmptyRegionFromKey(next.getRow());
        if (includeRegions == null || includeRegions.contains(emptyRegion)) {
          emptyRegions.add(emptyRegion);
        }
      }
    }
  }
  return Collections.unmodifiableSortedSet(emptyRegions);
}
 
Example 6
Source File: DataJanitorState.java    From phoenix-tephra with Apache License 2.0 6 votes vote down vote up
/**
 * Gets a list of {@link RegionPruneInfo} for given regions. Returns all regions if the given regions set is null.
 *
 * @param regions a set of regions
 * @return list of {@link RegionPruneInfo}s.
 * @throws IOException when not able to read the data from HBase
 */
public List<RegionPruneInfo> getPruneInfoForRegions(@Nullable SortedSet<byte[]> regions) throws IOException {
  List<RegionPruneInfo> regionPruneInfos = new ArrayList<>();
  try (Table stateTable = stateTableSupplier.get()) {
    byte[] startRow = makeRegionKey(EMPTY_BYTE_ARRAY);
    Scan scan = new Scan(startRow, REGION_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, PRUNE_UPPER_BOUND_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] region = getRegionFromKey(next.getRow());
        if (regions == null || regions.contains(region)) {
          Cell cell = next.getColumnLatestCell(FAMILY, PRUNE_UPPER_BOUND_COL);
          if (cell != null) {
            byte[] pruneUpperBoundBytes = CellUtil.cloneValue(cell);
            long timestamp = cell.getTimestamp();
            regionPruneInfos.add(new RegionPruneInfo(region, Bytes.toStringBinary(region),
                                                     Bytes.toLong(pruneUpperBoundBytes), timestamp));
          }
        }
      }
    }
  }
  return Collections.unmodifiableList(regionPruneInfos);
}
 
Example 7
Source File: FindPanel.java    From openjdk-jdk8u with GNU General Public License v2.0 6 votes vote down vote up
public void updateComboBox(List<Figure> figures) {

        String sel = (String) nameComboBox.getSelectedItem();
        SortedSet<String> propertyNames = new TreeSet<String>();

        for (Figure f : figures) {
            Properties prop = f.getProperties();
            for (Property p : prop) {
                if (!propertyNames.contains(p.getName())) {
                    propertyNames.add(p.getName());
                }
            }
        }

        for (String s : propertyNames) {
            nameComboBox.addItem(s);
        }
        nameComboBox.setSelectedItem(sel);
    }
 
Example 8
Source File: AgreementRoleCommunicationChannel.java    From estatio with Apache License 2.0 6 votes vote down vote up
public String validateSucceededBy(
        final CommunicationChannel communicationChannel,
        final LocalDate startDate, final LocalDate endDate) {
    String invalidReasonIfAny = helper.validateSucceededBy(startDate,
            endDate);
    if (invalidReasonIfAny != null) {
        return invalidReasonIfAny;
    }

    if (communicationChannel == getCommunicationChannel()) {
        return "Successor's communication channel cannot be the same as this object's communication channel";
    }
    final AgreementRoleCommunicationChannel successor = getSuccessor();
    if (successor != null
            && communicationChannel == successor.getCommunicationChannel()) {
        return "Successor's communication channel cannot be the same as that of existing successor";
    }
    final SortedSet<CommunicationChannel> partyChannels = communicationChannelsForRolesParty();
    if (!partyChannels.contains(communicationChannel)) {
        return "Successor's communication channel must be one of those of the parent role's party";
    }

    return null;
}
 
Example 9
Source File: DataJanitorState.java    From phoenix-tephra with Apache License 2.0 6 votes vote down vote up
/**
 * Gets a list of {@link RegionPruneInfo} for given regions. Returns all regions if the given regions set is null.
 *
 * @param regions a set of regions
 * @return list of {@link RegionPruneInfo}s.
 * @throws IOException when not able to read the data from HBase
 */
public List<RegionPruneInfo> getPruneInfoForRegions(@Nullable SortedSet<byte[]> regions) throws IOException {
  List<RegionPruneInfo> regionPruneInfos = new ArrayList<>();
  try (Table stateTable = stateTableSupplier.get()) {
    byte[] startRow = makeRegionKey(EMPTY_BYTE_ARRAY);
    Scan scan = new Scan(startRow, REGION_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, PRUNE_UPPER_BOUND_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] region = getRegionFromKey(next.getRow());
        if (regions == null || regions.contains(region)) {
          Cell cell = next.getColumnLatestCell(FAMILY, PRUNE_UPPER_BOUND_COL);
          if (cell != null) {
            byte[] pruneUpperBoundBytes = CellUtil.cloneValue(cell);
            long timestamp = cell.getTimestamp();
            regionPruneInfos.add(new RegionPruneInfo(region, Bytes.toStringBinary(region),
                                                     Bytes.toLong(pruneUpperBoundBytes), timestamp));
          }
        }
      }
    }
  }
  return Collections.unmodifiableList(regionPruneInfos);
}
 
Example 10
Source File: HtmlPage.java    From htmlunit with Apache License 2.0 6 votes vote down vote up
private void addElement(final Map<String, SortedSet<DomElement>> map, final DomElement element,
        final String attribute, final boolean recurse) {
    final String value = getAttributeValue(element, attribute);

    if (DomElement.ATTRIBUTE_NOT_DEFINED != value) {
        SortedSet<DomElement> elements = map.get(value);
        if (elements == null) {
            elements = new TreeSet<>(documentPositionComparator);
            elements.add(element);
            map.put(value, elements);
        }
        else if (!elements.contains(element)) {
            elements.add(element);
        }
    }
    if (recurse) {
        for (final DomElement child : element.getChildElements()) {
            addElement(map, child, attribute, true);
        }
    }
}
 
Example 11
Source File: DataJanitorState.java    From phoenix-tephra with Apache License 2.0 6 votes vote down vote up
/**
 * Return regions that were recorded as empty after the given time.
 *
 * @param time time in milliseconds
 * @param includeRegions If not null, the returned set will be an intersection of the includeRegions set
 *                       and the empty regions after the given time
 */
public SortedSet<byte[]> getEmptyRegionsAfterTime(long time, @Nullable SortedSet<byte[]> includeRegions)
  throws IOException {
  SortedSet<byte[]> emptyRegions = new TreeSet<>(Bytes.BYTES_COMPARATOR);
  try (HTableInterface stateTable = stateTableSupplier.get()) {
    Scan scan = new Scan(makeEmptyRegionTimeKey(Bytes.toBytes(time + 1), EMPTY_BYTE_ARRAY),
                         EMPTY_REGION_TIME_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, EMPTY_REGION_TIME_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] emptyRegion = getEmptyRegionFromKey(next.getRow());
        if (includeRegions == null || includeRegions.contains(emptyRegion)) {
          emptyRegions.add(emptyRegion);
        }
      }
    }
  }
  return Collections.unmodifiableSortedSet(emptyRegions);
}
 
Example 12
Source File: FindPanel.java    From jdk8u60 with GNU General Public License v2.0 6 votes vote down vote up
public void updateComboBox(List<Figure> figures) {

        String sel = (String) nameComboBox.getSelectedItem();
        SortedSet<String> propertyNames = new TreeSet<String>();

        for (Figure f : figures) {
            Properties prop = f.getProperties();
            for (Property p : prop) {
                if (!propertyNames.contains(p.getName())) {
                    propertyNames.add(p.getName());
                }
            }
        }

        for (String s : propertyNames) {
            nameComboBox.addItem(s);
        }
        nameComboBox.setSelectedItem(sel);
    }
 
Example 13
Source File: RuntimeClassLoaderFactory.java    From crnk-framework with Apache License 2.0 5 votes vote down vote up
public Set<File> getProjectLibraries() {
    Set<File> classpath = new HashSet<>();

    SourceSetContainer sourceSets = (SourceSetContainer) project.getProperties().get("sourceSets");

    if (sourceSets != null) {
        SortedSet<String> availableSourceSetNames = sourceSets.getNames();
        for (String sourceSetName : Arrays.asList("main", "test", "integrationTest")) {
            if (availableSourceSetNames.contains(sourceSetName)) {
                SourceSet sourceSet = sourceSets.getByName(sourceSetName);
                classpath.addAll(sourceSet.getOutput().getClassesDirs().getFiles());
                classpath.add(sourceSet.getOutput().getResourcesDir());
            }
        }
    }

    // add  dependencies from configured gradle configuration to url (usually test or integrationTest)
    GeneratorConfig generatorConfiguration = project.getExtensions().getByType(GeneratorExtension.class);
    String configurationName = generatorConfiguration.getRuntime().getConfiguration();

    ConfigurationContainer configurations = project.getConfigurations();
    Configuration runtimeConfiguration = configurations.findByName(configurationName + "Runtime");
    if (runtimeConfiguration == null) {
        runtimeConfiguration = configurations.getByName(configurationName);
    }
    classpath.addAll(runtimeConfiguration.getFiles());

    for (File file : classpath) {
        LOGGER.debug("classpath entry: {}", file);
    }

    return classpath;
}
 
Example 14
Source File: Regions.java    From APICloud-Studio with GNU General Public License v3.0 5 votes vote down vote up
/** Workaround for NavigatableSet interface which is @since java 1.6
 */

private static <T> T NavigableSetFloor(SortedSet<T> sortedSet, T e) {
	if (sortedSet.contains(e)) {
		return e;
	}
	SortedSet<T> headSet = sortedSet.headSet(e);
	if (headSet.isEmpty()) {
		return null;
	}
	return headSet.last();
}
 
Example 15
Source File: OrFilter.java    From heroic with Apache License 2.0 5 votes vote down vote up
static Filter optimize(final SortedSet<Filter> filters) {
    final SortedSet<Filter> result = new TreeSet<>();

    for (final Filter f : filters) {
        if (f instanceof NotFilter) {
            // Optimize away expressions which are always true.
            // Example: foo = bar or !(foo = bar)

            if (filters.contains(((NotFilter) f).filter())) {
                return TrueFilter.get();
            }
        } else if (f instanceof StartsWithFilter) {
            // Optimize away prefixes which encompass each other.
            // Example: foo ^ hello or foo ^ helloworld -> foo ^ hello

            if (FilterUtils.containsPrefixedWith(filters, (StartsWithFilter) f,
                (inner, outer) -> FilterUtils.prefixedWith(outer.value(),
                    inner.value()))) {
                continue;
            }
        }

        result.add(f);
    }

    if (result.isEmpty()) {
        return TrueFilter.get();
    }

    if (result.size() == 1) {
        return result.iterator().next();
    }

    return OrFilter.create(ImmutableList.copyOf(result));
}
 
Example 16
Source File: BundleMvnAntTask.java    From knopflerfish.org with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Add dependencies element for the given bundle to the string buffer.
 *
 * @param el
 *          element to add the dependencies to.
 * @param ba
 *          The bundle archive to defining the coordinates.
 * @param prefix
 *          Whitespace to add before the new element.
 */
private void addDependencies(Element el, BundleArchive ba, String prefix)
{
  final Element dependencies = el.getOwnerDocument().createElement("dependencies");
  final String prefix1 = prefix + "  ";
  final String prefix2 = prefix1 + "  ";

  el.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix1));
  el.appendChild(dependencies);
  el.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix));

  for (final Entry<BundleArchive,SortedSet<String>> depEntry : selectCtDeps(ba).entrySet()) {
    final BundleArchives.BundleArchive depBa = depEntry.getKey();
    final SortedSet<String> pkgNames = depEntry.getValue();

    dependencies.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix2));
    dependencies.appendChild(el.getOwnerDocument().createComment(pkgNames.toString()));

    final Element dependency = el.getOwnerDocument().createElement("dependency");
    addMavenCoordinates(dependency, depBa);
    if (pkgNames.contains("org.osgi.framework")) {
      dependency.setAttribute("scope", "provided");
    }

    dependencies.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix2));
    dependencies.appendChild(dependency);
    dependencies.appendChild(el.getOwnerDocument().createTextNode("\n"));
  }
  dependencies.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix1));

  if (0<ba.pkgUnprovidedMap.size()) {
    log("  Imports without any provider: " +ba.pkgUnprovidedMap,
        Project.MSG_DEBUG);
  }
}
 
Example 17
Source File: MemoryDataStoreOperations.java    From geowave with Apache License 2.0 5 votes vote down vote up
@Override
public void write(final GeoWaveRow row) {
  SortedSet<MemoryStoreEntry> rowTreeSet = storeData.get(indexName);
  if (rowTreeSet == null) {
    rowTreeSet = new TreeSet<>();
    storeData.put(indexName, rowTreeSet);
  }
  if (rowTreeSet.contains(new MemoryStoreEntry(row))) {
    rowTreeSet.remove(new MemoryStoreEntry(row));
  }
  if (!rowTreeSet.add(new MemoryStoreEntry(row))) {
    LOGGER.warn("Unable to add new entry");
  }
}
 
Example 18
Source File: PdxInstanceImpl.java    From gemfirexd-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Any fields that are in otherFields but not in myFields
 * are added to myFields as defaults. When adding fields they
 * are inserted in the natural sort order.
 * Note: myFields may be modified by this call.
 */
private static void addDefaultFields(SortedSet<PdxField> myFields, SortedSet<PdxField> otherFields) {
  for (PdxField f: otherFields) {
    if (!myFields.contains(f)) {
      myFields.add(new DefaultPdxField(f));
    }
  }
}
 
Example 19
Source File: TargetPanel.java    From knopflerfish.org with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Load all targeted factory configuration instances and update user interface
 * to show them.
 *
 * @param selectedPid
 *          If this PID is available then select it, otherwise select the last
 *          PID. If {@link #nextFactoryPidToSelect} is non-null then select
 *          that configuration instance and set the field to {@code null}.
 */
private void updateSelectionFactoryPID(String selectedPid)
{
  synchronized (pid2Cfg) {
    pid2Cfg.clear();
    if (selectedPid == null) {
      selectedPid = "";
    }

    for (int i = 0; i < MAX_SIZE; i++) {
      try {
        final Configuration[] configs =
          CMDisplayer.getCA().listConfigurations("(service.factoryPid="
                                                     + targetedPids[i] + ")");
        if (configs != null) {
          for (final Configuration cfg : configs) {
            pid2Cfg.put(cfg.getPid(), cfg);
          }
        }
      } catch (final Exception e) {
        Activator.log
            .error("Faile to load factory configuration instances for fpid '"
                   + targetedPids[i] + "': " + e.getMessage(), e);
      }
    }

    final SortedSet<String> instancePIDs =
      new TreeSet<String>(pid2Cfg.keySet());
    instancePIDs.add(FACTORY_PID_DEFAULTS);

    final DefaultComboBoxModel model =
      new DefaultComboBoxModel(instancePIDs.toArray());
    if (nextFactoryPidToSelect != null) {
      if (instancePIDs.contains(nextFactoryPidToSelect)) {
        selectedPid = nextFactoryPidToSelect;
      }
      nextFactoryPidToSelect = null;
    } else if (!instancePIDs.contains(selectedPid)) {
      // New selection needed, use last PID.
      selectedPid = (String) model.getElementAt(model.getSize() - 1);
    }
    model.setSelectedItem(selectedPid);
    fbox.setModel(model);
    final Configuration selectedCfg = pid2Cfg.get(selectedPid);

    // Update the targeted PID selectors to match the target selectors in the
    // factory PID of the selected instance.
    final String fpid =
      selectedCfg != null ? selectedCfg.getFactoryPid() : targetedPids[0];
    String tpid = null;
    for (int i = 0; i < MAX_SIZE && null != (tpid = targetedPids[i]); i++) {
      rbs[i].setToolTipText(TARGET_LEVEL_FACOTRY_PID_TOOLTIPS[i] + tpid
                            + "</code></p></html>");

      if (fpid.equals(targetedPids[i])) {
        rbs[i].setSelected(true);
        selectedTargetLevel = i;
        if (selectedCfg != null) {
          icons[i].setIcon(openDocumentIcon);
          icons[i].setToolTipText("exists");
        } else {
          icons[i].setIcon(newDocumentIcon);
          icons[i].setToolTipText("to be created");
        }
      } else {
        icons[i].setIcon(newDocumentIcon);
        icons[i].setToolTipText("to be created");
      }
    }
  }
}
 
Example 20
Source File: LayoutVersion.java    From big-c with Apache License 2.0 2 votes vote down vote up
/**
 * Returns true if a given feature is supported in the given layout version
 * @param map layout feature map
 * @param f Feature
 * @param lv LayoutVersion
 * @return true if {@code f} is supported in layout version {@code lv}
 */
public static boolean supports(Map<Integer, SortedSet<LayoutFeature>> map,
    final LayoutFeature f, final int lv) {
  final SortedSet<LayoutFeature> set =  map.get(lv);
  return set != null && set.contains(f);
}