((ArrayList<NavigableSet<ObjId>>)result .computeIfAbsent(fieldStorageId, i -> new ArrayList<NavigableSet<ObjId>>(versionList.size()))) .add(NavigableSets.intersection(schemaVersionRefs, referrers)); } else for (Map.Entry<Integer, Object> entry : result.entrySet()) { final ArrayList<NavigableSet<ObjId>> list = (ArrayList<NavigableSet<ObjId>>)entry.getValue(); final NavigableSet<ObjId> union = list.size() == 1 ? list.get(0) : NavigableSets.union(list); entry.setValue(union);
if (monitors == null || monitors.isEmpty()) continue; this.notifyFieldMonitors(notifier, NavigableSets.singleton(notifier.getId()), new ArrayList<>(monitors), 0);
refsList.addAll(this.traverseReference(objects, -storageId, monitor.getFilter(step + 1))); if (!refsList.isEmpty()) this.notifyFieldMonitors(notifier, NavigableSets.union(refsList), monitors, step + 1);
/** * Determine if there are any monitors watching any field in the specified type. */ boolean hasFieldMonitor(ObjType objType) { assert Thread.holdsLock(this); // Do quick check, if possible if (this.monitorMap == null) return false; final int objTypeStorageId = objType.storageId; if (this.hasFieldMonitorCache != null) { final long minKey = this.buildHasFieldMonitorCacheKey(objTypeStorageId, 0); if (objTypeStorageId == Integer.MAX_VALUE) return this.hasFieldMonitorCache.ceiling(minKey) != null; final long maxKey = this.buildHasFieldMonitorCacheKey(objTypeStorageId + 1, 0); return !this.hasFieldMonitorCache.subSet(minKey, maxKey).isEmpty(); } // Do slow check for (int fieldStorageId : NavigableSets.intersection(objType.fields.navigableKeySet(), this.monitorMap.navigableKeySet())) { if (this.monitorMap.get(fieldStorageId).stream().anyMatch(new MonitoredPredicate(objTypeStorageId, fieldStorageId))) return true; } return false; }
/** * Find all objects of the given type referring to this object through the specified reference field. * * <p> * The {@code fieldName} can be the name of a simple reference field (e.g., {@code "teacher"}) * or a sub-field of a complex field (e.g., {@code "students.element"}). * * @param type type of referring objects * @param fieldName name of reference field * @param <R> type of referring objects * @return all objects of the specified type referring to this object through the named field * @throws io.permazen.kv.StaleTransactionException if the transaction associated with this instance is no longer open * @throws IllegalArgumentException if either parameter is null */ default <R> NavigableSet<R> findReferring(Class<R> type, String fieldName) { final NavigableSet<R> set = this.getTransaction().queryIndex(type, fieldName, Object.class).asMap().get(this); return set != null ? set : NavigableSets.empty(); }
((NavigableSet<?>)thisValue).comparator().equals(((NavigableSet<?>)thatValue).comparator()) : ((NavigableSet<?>)thatValue).comparator() == null)) return new ConstValue(NavigableSets.difference((NavigableSet<Object>)thisValue, (NavigableSet<Object>)thatValue));
((NavigableSet<?>)thisValue).comparator().equals(((NavigableSet<?>)thatValue).comparator()) : ((NavigableSet<?>)thatValue).comparator() == null)) { return new ConstValue(NavigableSets.symmetricDifference((NavigableSet<Object>)thisValue, (NavigableSet<Object>)thatValue));
@Override public Diffs differencesFrom(SchemaModel that) { Preconditions.checkArgument(that != null, "null that"); final Diffs diffs = new Diffs(); final NavigableSet<Integer> allObjectTypeIds = NavigableSets.union( this.schemaObjectTypes.navigableKeySet(), that.schemaObjectTypes.navigableKeySet()); for (int storageId : allObjectTypeIds) { final SchemaObjectType thisObjectType = this.schemaObjectTypes.get(storageId); final SchemaObjectType thatObjectType = that.schemaObjectTypes.get(storageId); if (thisObjectType == null) diffs.add("removed " + thatObjectType); else if (thatObjectType == null) diffs.add("added " + thisObjectType); else { final Diffs objectTypeDiffs = thisObjectType.differencesFrom(thatObjectType); if (!objectTypeDiffs.isEmpty()) diffs.add("changed " + thatObjectType, objectTypeDiffs); } } return diffs; }
@Override @SuppressWarnings("unchecked") public Value and(ParseSession session, Value that) { // Handle boolean final Object thisValue = this.checkNotNull(session, "`and'"); final Object thatValue = that.checkNotNull(session, "`and'"); if (thisValue instanceof Boolean && thatValue instanceof Boolean) return new ConstValue((Boolean)thisValue & (Boolean)thatValue); // Handle NavigableSet with equal comparators XXX might not have compatible elements if (thisValue instanceof NavigableSet && thatValue instanceof NavigableSet && (((NavigableSet<?>)thisValue).comparator() != null ? ((NavigableSet<?>)thisValue).comparator().equals(((NavigableSet<?>)thatValue).comparator()) : ((NavigableSet<?>)thatValue).comparator() == null)) return new ConstValue(NavigableSets.intersection((NavigableSet<Object>)thisValue, (NavigableSet<Object>)thatValue)); // Handle Set if (thisValue instanceof Set && thatValue instanceof Set) return new ConstValue(Sets.intersection((Set<Object>)thisValue, (Set<Object>)thatValue)); // Handle numeric final Number lnum = AbstractValue.promoteNumeric(session, thisValue, "`and'", thatValue); final Number rnum = AbstractValue.promoteNumeric(session, thatValue, "`and'", thisValue); if (!(lnum instanceof Integer) && !(lnum instanceof Long) && !(lnum instanceof BigInteger)) throw new EvalException("invalid `and' operation on " + AbstractValue.describeType(lnum)); if (lnum instanceof BigInteger) return new ConstValue(((BigInteger)lnum).and((BigInteger)rnum)); if (lnum instanceof Long) return new ConstValue((Long)lnum & (Long)rnum); return new ConstValue((Integer)lnum & (Integer)rnum); }
for (ObjId id : Iterables.limit(NavigableSets.union(idSets), MAX_COMPLETE_OBJECTS)) this.completions.add(id.toString());
final NavigableSet<Integer> allFieldIds = NavigableSets.union( this.schemaFields.navigableKeySet(), that.schemaFields.navigableKeySet()); for (int storageId : allFieldIds) { final NavigableSet<Integer> allIndexIds = NavigableSets.union( this.schemaCompositeIndexes.navigableKeySet(), that.schemaCompositeIndexes.navigableKeySet()); for (int storageId : allIndexIds) {
@Override @SuppressWarnings("unchecked") public Value or(ParseSession session, Value that) { // Handle boolean final Object thisValue = this.checkNotNull(session, "`or'"); final Object thatValue = that.checkNotNull(session, "`or'"); if (thisValue instanceof Boolean && thatValue instanceof Boolean) return new ConstValue((Boolean)thisValue | (Boolean)thatValue); // Handle NavigableSet with equal comparators XXX might not have compatible elements if (thisValue instanceof NavigableSet && thatValue instanceof NavigableSet && (((NavigableSet<?>)thisValue).comparator() != null ? ((NavigableSet<?>)thisValue).comparator().equals(((NavigableSet<?>)thatValue).comparator()) : ((NavigableSet<?>)thatValue).comparator() == null)) return new ConstValue(NavigableSets.union((NavigableSet<Object>)thisValue, (NavigableSet<Object>)thatValue)); // Handle Set if (thisValue instanceof Set && thatValue instanceof Set) return new ConstValue(Sets.union((Set<Object>)thisValue, (Set<Object>)thatValue)); // Handle numeric final Number lnum = AbstractValue.promoteNumeric(session, thisValue, "`or'", thatValue); final Number rnum = AbstractValue.promoteNumeric(session, thatValue, "`or'", thisValue); if (!(lnum instanceof Integer) && !(lnum instanceof Long) && !(lnum instanceof BigInteger)) throw new EvalException("invalid `or' operation on " + AbstractValue.describeType(lnum)); if (lnum instanceof BigInteger) return new ConstValue(((BigInteger)lnum).or((BigInteger)rnum)); if (lnum instanceof Long) return new ConstValue((Long)lnum | (Long)rnum); return new ConstValue((Integer)lnum | (Integer)rnum); }