@Override public int size() { return attributes.size(); } };
@Override public int size() { return layout.attributes.size(); } };
@Override public int size() { return attributeNames.size(); } };
@Override public Iterator<Attribute<?>> iterator() { return (Iterator) IntStream.range(0, layout.attributes.size()) .mapToObj(i -> { Object val = layout.getters.get(i).get(AbstractBeanEntity.this); if (val == null) { return null; } else { return Attribute.create((TypedName) layout.attributes.getAttribute(i), val); } }) .filter(Predicates.notNull()) .iterator(); }
@Override public Iterable<Entity> entities() { AttrStore[] stores = new AttrStore[storeBuilders.length]; for (int i = 0; i < stores.length; i++) { stores[i] = storeBuilders[i].tempBuild(); } // the packed collection is not fully functional! But it will be iterable. return new PackedEntityCollection(entityType, attributes, stores, new PackIndex[attributes.size()], entityBuilderClass); }
@Override public Set<TypedName<?>> getTypedAttributeNames() { int missing = 0; int na = attributes.size(); for (int i = 0; i < na; i++) { if (attrStores[i].isNull(position)) { missing |= 1 << i; } } if (missing != 0) { AttributeSet set = attrSets.get(missing); if (set == null) { set = AttributeSet.create(IntStream.range(0, na) .filter(i -> !attrStores[i].isNull(position)) .mapToObj(attributes::getAttribute) .collect(Collectors.toList())); attrSets.put(missing, set); } return set; } return attributes; }
@Override public Iterator<Attribute<?>> iterator() { return (Iterator) IntStream.range(0, attributeNames.size()) .mapToObj(i -> { if (i == 0) { return Attribute.create(CommonAttributes.ENTITY_ID, getId()); } Object val = attributeValues[i-1]; if (val == null) { return null; } else { return Attribute.create((TypedName) attributeNames.getAttribute(i), val); } }) .filter(Predicates.notNull()) .iterator(); }
/** * Create a new packed entity collection builder. * @param type The entity type. * @param attrs The attributes to store. * @return An entity collection builder. */ public static EntityCollectionBuilder newBuilder(EntityType type, AttributeSet attrs) { Preconditions.checkArgument(attrs.lookup(CommonAttributes.ENTITY_ID) == 0, "could not find entity ID in: %s", attrs); if (attrs.size() > 1) { return new PackedEntityCollectionBuilder(type, attrs, null); } else { return new BareEntityCollectionBuilder(type); } }
@Override public Entity build() { Preconditions.checkState(type != null, "Entity type not set"); Preconditions.checkState(idSet, "ID not set"); if (attributes.isEmpty() || attributes.keySet().equals(Collections.singleton(CommonAttributes.ENTITY_ID))) { return new BareEntity(type, id); } else { List<TypedName<?>> names = new ArrayList<>(attributes.size()); names.add(CommonAttributes.ENTITY_ID); for (Attribute<?> a: attributes.values()) { names.add(a.getTypedName()); } assert names.lastIndexOf(CommonAttributes.ENTITY_ID) == 0; AttributeSet aset = AttributeSet.create(names); Object[] values = new Object[aset.size()]; for (Attribute<?> a: attributes.values()) { int i = aset.lookup(a.getTypedName()); values[i-1] = a.getValue(); } return new BasicEntity(type, id, aset, values); } } }
/** * Create a new packed entity collection builder. * @param type The entity type. * @param attrs The attributes to store. * @param eb An entity builder to use when reconstituting entities. * @return An entity collection builder. */ public static EntityCollectionBuilder newBuilder(EntityType type, AttributeSet attrs, Class<? extends EntityBuilder> eb) { Preconditions.checkArgument(attrs.lookup(CommonAttributes.ENTITY_ID) == 0, "could not find entity ID in: %s", attrs); if (attrs.size() > 1) { return new PackedEntityCollectionBuilder(type, attrs, eb); } else { return new BareEntityCollectionBuilder(type); } }
@Override public void describeTo(DescriptionWriter writer) { writer.putField("entity_count", size); writer.putList("attributes", attributes); if (contentHash == null) { Hasher hash = Hashing.md5().newHasher(); for (int i = 0; i < size; i++) { hash.putLong(idStore.getLong(i)); for (int j = 1; j < attributes.size(); j++) { hash.putInt(Objects.hashCode(attrStores[j].get(i))); } } contentHash = hash.hash(); } writer.putField("content_hash", contentHash); }
PackedEntityCollectionBuilder(EntityType et, AttributeSet attrs, Class<? extends EntityBuilder> ebc) { Preconditions.checkArgument(attrs.size() > 0, "attribute set is emtpy"); Preconditions.checkArgument(attrs.size() < 32, "cannot have more than 31 attributes"); Preconditions.checkArgument(attrs.getAttribute(0) == CommonAttributes.ENTITY_ID, "attribute set does not contain entity ID attribute"); entityType = et; attributes = attrs; int n = attrs.size(); storeBuilders = new AttrStoreBuilder[n]; needIndex = new boolean[n];
@Override public Entity apply(int position) { EntityBuilder eb = factory.newInstance(); eb.setId(idStore.getLong(position)); for (int i = 1; i < attributes.size(); i++) { storeSetters[i].invoke(eb, position); } return eb.build(); } }
@Test public void testBasicSingleAttribute() { AttributeSet attrs = AttributeSet.create(CommonAttributes.ENTITY_ID); assertThat(attrs.size(), equalTo(1)); assertThat(attrs.lookup(CommonAttributes.ENTITY_ID), equalTo(0)); assertThat(attrs.lookup(CommonAttributes.ITEM_ID), equalTo(-1)); assertThat(attrs, contains(CommonAttributes.ENTITY_ID)); assertThat(attrs.contains(CommonAttributes.ENTITY_ID), equalTo(true)); assertThat(attrs.contains(CommonAttributes.NAME), equalTo(false)); }
@Override public int size() { return attributeNames.size(); } };
@Override public int size() { return attributes.size(); } };
@Override public int size() { return layout.attributes.size(); } };
@Override public Iterator<Attribute<?>> iterator() { return (Iterator) IntStream.range(0, layout.attributes.size()) .mapToObj(i -> { Object val = layout.getters.get(i).get(AbstractBeanEntity.this); if (val == null) { return null; } else { return Attribute.create((TypedName) layout.attributes.getAttribute(i), val); } }) .filter(Predicates.notNull()) .iterator(); }
@Override public Iterable<Entity> entities() { AttrStore[] stores = new AttrStore[storeBuilders.length]; for (int i = 0; i < stores.length; i++) { stores[i] = storeBuilders[i].tempBuild(); } // the packed collection is not fully functional! But it will be iterable. return new PackedEntityCollection(entityType, attributes, stores, new PackIndex[attributes.size()], entityBuilderClass); }
@Override public Entity apply(int position) { EntityBuilder eb = factory.newInstance(); eb.setId(idStore.getLong(position)); for (int i = 1; i < attributes.size(); i++) { storeSetters[i].invoke(eb, position); } return eb.build(); } }