/// <summary> /// Given a collection of entity instances that used to /// belong to the collection, and a collection of instances /// that currently belong, return a collection of orphans /// </summary> protected static ICollection GetOrphans(ICollection oldElements, ICollection currentElements, string entityName, ISessionImplementor session) { // short-circuit(s) if (currentElements.Count == 0) { // no new elements, the old list contains only Orphans return oldElements; } if (oldElements.Count == 0) { // no old elements, so no Orphans neither return oldElements; } IType idType = session.Factory.GetEntityPersister(entityName).IdentifierType; // create the collection holding the orphans List<object> res = new List<object>(); // collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access HashedSet<TypedValue> currentIds = new HashedSet<TypedValue>(); foreach (object current in currentElements) { if (current != null && ForeignKeys.IsNotTransient(entityName, current, null, session)) { object currentId = ForeignKeys.GetEntityIdentifierIfNotUnsaved(entityName, current, session); currentIds.Add(new TypedValue(idType, currentId, session.EntityMode)); } } // iterate over the *old* list foreach (object old in oldElements) { object oldId = ForeignKeys.GetEntityIdentifierIfNotUnsaved(entityName, old, session); if (!currentIds.Contains(new TypedValue(idType, oldId, session.EntityMode))) { res.Add(old); } } return res; }
public IRStatistics Evaluate(RecommenderBuilder recommenderBuilder, DataModel dataModel, int at, double relevanceThreshold, double evaluationPercentage) { if (recommenderBuilder == null) { throw new ArgumentNullException("recommenderBuilder is null"); } if (dataModel == null) { throw new ArgumentNullException("dataModel is null"); } if (at < 1) { throw new ArgumentException("at must be at least 1"); } if (double.IsNaN(evaluationPercentage) || evaluationPercentage <= 0.0 || evaluationPercentage > 1.0) { throw new ArgumentException("Invalid evaluationPercentage: " + evaluationPercentage); } if (double.IsNaN(relevanceThreshold)) { throw new ArgumentException("Invalid relevanceThreshold: " + evaluationPercentage); } RunningAverage precision = new FullRunningAverage(); RunningAverage recall = new FullRunningAverage(); foreach (User user in dataModel.GetUsers()) { Object id = user.ID; if (random.NextDouble() < evaluationPercentage) { ICollection<Item> relevantItems = new HashedSet<Item>(/* at */); Preference[] prefs = user.GetPreferencesAsArray(); foreach (Preference pref in prefs) { if (pref.Value >= relevanceThreshold) { relevantItems.Add(pref.Item); } } int numRelevantItems = relevantItems.Count; if (numRelevantItems > 0) { ICollection<User> trainingUsers = new List<User>(dataModel.GetNumUsers()); foreach (User user2 in dataModel.GetUsers()) { if (id.Equals(user2.ID)) { ICollection<Preference> trainingPrefs = new List<Preference>(); prefs = user2.GetPreferencesAsArray(); foreach (Preference pref in prefs) { if (!relevantItems.Contains(pref.Item)) { trainingPrefs.Add(pref); } } if (trainingPrefs.Count > 0) { User trainingUser = new GenericUser<String>(id.ToString(), trainingPrefs); trainingUsers.Add(trainingUser); } } else { trainingUsers.Add(user2); } } DataModel trainingModel = new GenericDataModel(trainingUsers); Recommender recommender = recommenderBuilder.BuildRecommender(trainingModel); try { trainingModel.GetUser(id); } catch (NoSuchElementException) { continue; // Oops we excluded all prefs for the user -- just move on } int intersectionSize = 0; foreach (RecommendedItem recommendedItem in recommender.Recommend(id, at)) { if (relevantItems.Contains(recommendedItem.Item)) { intersectionSize++; } } precision.AddDatum((double) intersectionSize / (double) at); recall.AddDatum((double) intersectionSize / (double) numRelevantItems); } } } return new IRStatisticsImpl(precision.Average, recall.Average); }
private IDictionary<string, string[]> BindPropertyResults(string alias, HbmReturnDiscriminator discriminatorSchema, HbmReturnProperty[] returnProperties, PersistentClass pc) { Dictionary<string, string[]> propertyresults = new Dictionary<string, string[]>(); // maybe a concrete SQLpropertyresult type, but Map is exactly what is required at the moment if (discriminatorSchema != null) { propertyresults["class"] = GetResultColumns(discriminatorSchema).ToArray(); } List<HbmReturnProperty> properties = new List<HbmReturnProperty>(); List<string> propertyNames = new List<string>(); foreach (HbmReturnProperty returnPropertySchema in returnProperties ?? new HbmReturnProperty[0]) { string name = returnPropertySchema.name; if (pc == null || name.IndexOf('.') == -1) { //if dotted and not load-collection nor return-join //regular property properties.Add(returnPropertySchema); propertyNames.Add(name); } else { // Reorder properties // 1. get the parent property // 2. list all the properties following the expected one in the parent property // 3. calculate the lowest index and insert the property int dotIndex = name.LastIndexOf('.'); string reducedName = name.Substring(0, dotIndex); IValue value = pc.GetRecursiveProperty(reducedName).Value; IEnumerable<Mapping.Property> parentPropIter; if (value is Component) { Component comp = (Component) value; parentPropIter = comp.PropertyIterator; } else if (value is ToOne) { ToOne toOne = (ToOne) value; PersistentClass referencedPc = mappings.GetClass(toOne.ReferencedEntityName); if (toOne.ReferencedPropertyName != null) try { parentPropIter = ((Component) referencedPc.GetRecursiveProperty(toOne.ReferencedPropertyName).Value).PropertyIterator; } catch (InvalidCastException e) { throw new MappingException("dotted notation reference neither a component nor a many/one to one", e); } else try { parentPropIter = ((Component) referencedPc.IdentifierProperty.Value).PropertyIterator; } catch (InvalidCastException e) { throw new MappingException("dotted notation reference neither a component nor a many/one to one", e); } } else throw new MappingException("dotted notation reference neither a component nor a many/one to one"); bool hasFollowers = false; List<string> followers = new List<string>(); foreach (Mapping.Property prop in parentPropIter) { string currentPropertyName = prop.Name; string currentName = reducedName + '.' + currentPropertyName; if (hasFollowers) followers.Add(currentName); if (name.Equals(currentName)) hasFollowers = true; } int index = propertyNames.Count; int followersSize = followers.Count; for (int loop = 0; loop < followersSize; loop++) { string follower = followers[loop]; int currentIndex = GetIndexOfFirstMatchingProperty(propertyNames, follower); index = currentIndex != -1 && currentIndex < index ? currentIndex : index; } propertyNames.Insert(index, name); properties.Insert(index, returnPropertySchema); } } ISet<string> uniqueReturnProperty = new HashedSet<string>(); foreach (HbmReturnProperty returnPropertySchema in properties) { string name = returnPropertySchema.name; if ("class".Equals(name)) throw new MappingException( "class is not a valid property name to use in a <return-property>, use <return-discriminator> instead" ); //TODO: validate existing of property with the chosen name. (secondpass ) List<string> allResultColumns = GetResultColumns(returnPropertySchema); if (allResultColumns.Count == 0) throw new MappingException( "return-property for alias " + alias + " must specify at least one column or return-column name" ); if (uniqueReturnProperty.Contains(name)) throw new MappingException( "duplicate return-property for property " + name + " on alias " + alias ); uniqueReturnProperty.Add(name); // the issue here is that for <return-join/> representing an entity collection, // the collection element values (the property values of the associated entity) // are represented as 'element.{propertyname}'. Thus the StringHelper.root() // here puts everything under 'element' (which additionally has significant // meaning). Probably what we need to do is to something like this instead: // String root = StringHelper.root( name ); // String key = root; // by default // if ( !root.equals( name ) ) { // // we had a dot // if ( !root.equals( alias ) { // // the root does not apply to the specific alias // if ( "elements".equals( root ) { // // we specifically have a <return-join/> representing an entity collection // // and this <return-property/> is one of that entity's properties // key = name; // } // } // } // but I am not clear enough on the intended purpose of this code block, especially // in relation to the "Reorder properties" code block above... // String key = StringHelper.root( name ); string key = name; string[] intermediateResults; if (!propertyresults.TryGetValue(key,out intermediateResults)) propertyresults[key] = allResultColumns.ToArray(); else ArrayHelper.AddAll(intermediateResults, allResultColumns); // TODO: intermediateResults not used after this } Dictionary<string, string[]> newPropertyResults = new Dictionary<string, string[]>(); foreach (KeyValuePair<string, string[]> entry in propertyresults) { newPropertyResults[entry.Key] = entry.Value; } return newPropertyResults.Count == 0 ? (IDictionary<string, string[]>)new CollectionHelper.EmptyMapClass<string, string[]>() : newPropertyResults; }
/// <summary> /// Compute depths for all dirEdges via breadth-first traversal of nodes in graph. /// </summary> /// <param name="startEdge">Edge to start processing with.</param> // <FIX> MD - use iteration & queue rather than recursion, for speed and robustness private void ComputeDepths(DirectedEdge startEdge) { ISet nodesVisited = new HashedSet(); Queue nodeQueue = new Queue(); Node startNode = startEdge.Node; nodeQueue.Enqueue(startNode); nodesVisited.Add(startNode); startEdge.Visited = true; while (nodeQueue.Count != 0) { Node n = (Node) nodeQueue.Dequeue(); nodesVisited.Add(n); // compute depths around node, starting at this edge since it has depths assigned ComputeNodeDepth(n); // add all adjacent nodes to process queue, unless the node has been visited already IEnumerator i = ((DirectedEdgeStar)n.Edges).GetEnumerator(); while (i.MoveNext()) { DirectedEdge de = (DirectedEdge) i.Current; DirectedEdge sym = de.Sym; if (sym.IsVisited) continue; Node adjNode = sym.Node; if (!(nodesVisited.Contains(adjNode))) { nodeQueue.Enqueue(adjNode); nodesVisited.Add(adjNode); } } } }