public String getGainAttribute() { if (attribute == null) { return CommonAttributes.RATING.getName(); } else { return attribute; } }
/** * Construct a new nDCG Top-N metric. * @param disc The discount to apply. * @param name The column name to use. */ public TopNNDCGMetric(Discount disc, String name) { this(disc, name, CommonAttributes.RATING.getName()); }
/** * Get the attribute's name. * @return The attributge name. */ @Nonnull public String getName() { return name.getName(); }
/** * Look up an attribute. * @param name The attribute name. * @return The attribute's index, or a negative value if it does not exist. */ public int lookup(String name) { name = name.intern(); for (int i = 0; i < names.length; i++) { TypedName<?> n = names[i]; if (n.getName() == name) { return i; } } return -1; }
@Override public EntityBuilder clearAttribute(TypedName<?> name) { Preconditions.checkNotNull(name, "attribute"); attributes.remove(name.getName()); if (name == CommonAttributes.ENTITY_ID) { idSet = false; } return this; }
/** * Add an attribute to the list of expected attributes. It will be parsed from the JSON object field of the same * name. * @param attr The attribute to add. */ public void addAttribute(TypedName<?> attr) { addAttribute(attr.getName(), attr); }
@Override @Nonnull public <T> List<Entity> find(TypedName<T> name, T value) { return find(name.getName(), value); }
/** * Construct a set of entity defaults. * @param type The entity type. * @param attrs The well-known attributes. * @param cols The default column layout. */ public EntityDefaults(EntityType type, Collection<TypedName<?>> attrs, List<TypedName<?>> cols, Class<? extends EntityBuilder> bld, List<EntityDerivation> derivs) { entityType = type; ImmutableMap.Builder<String,TypedName<?>> abld = ImmutableMap.builder(); for (TypedName<?> a: attrs) { abld.put(a.getName(), a); } attributes = abld.build(); defaultColumns = ImmutableList.copyOf(cols); defaultBuilder = bld; defaultDerivations = ImmutableList.copyOf(derivs); }
/** * {@inheritDoc} * * Delegates to {@link #getTypedAttributeNames()} and extracts the names. */ @Override public Set<String> getAttributeNames() { // TODO Make this more efficient ImmutableSet.Builder<String> bld = ImmutableSet.builder(); for (TypedName<?> name: getTypedAttributeNames()) { bld.add(name.getName()); } return bld.build(); }
@Override public <T> EntityCollectionBuilder addIndex(TypedName<T> attribute) { Preconditions.checkState(indexBuilders != null, "build() already called"); if (indexBuilders.containsKey(attribute.getName())) { // already have that index return this; } EntityIndexBuilder ib = EntityIndexBuilder.create(attribute); indexBuilders.put(attribute.getName(), ib); for (Entity e: store.build()) { ib.add(e); } return this; }
@Override public Map.Entry<String, Object> next() { TypedName<?> attr = baseIter.next(); return ImmutablePair.of(attr.getName(), get(attr)); }
/** * {@inheritDoc} * * This implementation delegates to {@link #hasAttribute(String)} */ @Override public boolean hasAttribute(TypedName<?> name) { Object value = maybeGet(name.getName()); return value != null && name.getRawType().isInstance(value); }
/** * {@inheritDoc} * * This implementation delegates to {@link #maybeGet(String)} and checks the type. */ @Nullable @Override public <T> T maybeGet(TypedName<T> name) { try { // FIXME This is not fully type-safe! return (T) name.getRawType().cast(maybeGet(name.getName())); } catch (ClassCastException e) { throw new IllegalArgumentException(e); } }
@Override protected boolean doEquivalent(TypedName<?> a, TypedName<?> b) { return a == b || (a.name.equals(b.getName()) && a.type.equals(b.getType())); }
@Override public <T> EntityBuilder setAttribute(TypedName<T> name, T val) { Preconditions.checkNotNull(name, "attribute"); Preconditions.checkNotNull(val, "value"); Preconditions.checkArgument(name.getRawType().isInstance(val), "value %s not of type %s", val, name.getType()); if (name == CommonAttributes.ENTITY_ID) { return setId(((Long) val).longValue()); } else { attributes.put(name.getName(), Attribute.create(name, val)); return this; } }
@Override public ObjectNode toJSON() { JsonNodeFactory nf = JsonNodeFactory.instance; ObjectNode json = nf.objectNode(); json.put("format", "json"); json.put("entity_type", entityType.getName()); if (!attributes.isEmpty()) { ObjectNode attrNode = json.putObject("attributes"); for (Map.Entry<String,TypedName<?>> attr: attributes.entrySet()) { ObjectNode an = attrNode.putObject(attr.getKey()); an.put("name", attr.getValue().getName()); an.put("type", TypeUtils.makeTypeName(attr.getValue().getType())); } } return json; }
@Override public Map<Long,List<Entity>> grouped(TypedName<Long> attr) { Preconditions.checkArgument(attr != CommonAttributes.ENTITY_ID, "cannot group by entity ID"); EntityIndex idx = indexes.get(attr.getName()); if (idx == null) { return store.values() .stream() .filter(e -> e.hasAttribute(attr)) .collect(Collectors.groupingBy(e -> e.getLong(attr))); } else { return idx.getValues() .stream() .collect(Collectors.toMap(l -> (Long) l, idx::getEntities)); } }
/** * Look up an attribute. * @param name The attribute. * @param matchSubclasses If true, then attributes whose types are subclasses of `name`'s type will also match. * @return The attribute's index, or a negative value if it does not exist. Nonexistence is further * differentiated with -1 for no attribute, -2 for type mismatch. */ public int lookup(TypedName<?> name, boolean matchSubclasses) { // Linear search with interned objects is faster for short lists for (int i = 0; i < names.length; i++) { TypedName<?> n = names[i]; if (n == name) { return i; } else if (n.getName() == name.getName()) { if (matchSubclasses && n.getType().isSubtypeOf(name.getType())) { return i; } else { // FIXME Handle typecasting return -2; } } } return -1; }
for (TypedName<?> col: columns) { ObjectNode colObj = cols.addObject(); colObj.put("name", col.getName()); colObj.put("type", TypeUtils.makeTypeName(col.getType())); for (Map.Entry<String,TypedName<?>> colE: labeledColumns.entrySet()) { ObjectNode colNode = cols.putObject(colE.getKey()); colNode.put("name", colE.getValue().getName()); colNode.put("type", TypeUtils.makeTypeName(colE.getValue().getType()));
@Test public void testBasicField() { TypedName<String> attribute = TypedName.create("foo", String.class); assertThat(attribute.getName(), equalTo("foo")); assertThat(attribute.getType(), equalTo(TypeToken.of(String.class))); // check equality to random other object assertThat(attribute, not(equalTo((Object) "foo"))); assertThat(TypedName.create("foo", String.class), sameInstance(attribute)); assertThat(attribute.toString(), notNullValue()); assertThat(attribute.toString(), matchesPattern("^TypedName\\[foo: .*\\]$")); }