PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/Libraries/core/net40/Query/Algebra/Distinct.cs

http://dotnetrdf.codeplex.com
C# | 316 lines | 190 code | 23 blank | 103 comment | 8 complexity | a04352f94c2a849b7199177e87abc651 MD5 | raw file
Possible License(s): MIT
  1. /*
  2. dotNetRDF is free and open source software licensed under the MIT License
  3. -----------------------------------------------------------------------------
  4. Copyright (c) 2009-2012 dotNetRDF Project (dotnetrdf-developer@lists.sf.net)
  5. Permission is hereby granted, free of charge, to any person obtaining a copy
  6. of this software and associated documentation files (the "Software"), to deal
  7. in the Software without restriction, including without limitation the rights
  8. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the Software is furnished
  10. to do so, subject to the following conditions:
  11. The above copyright notice and this permission notice shall be included in all
  12. copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  17. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  18. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. */
  20. using System;
  21. using System.Collections.Generic;
  22. using System.Linq;
  23. using VDS.RDF.Query.Optimisation;
  24. using VDS.RDF.Query.Patterns;
  25. namespace VDS.RDF.Query.Algebra
  26. {
  27. /// <summary>
  28. /// Represents a Distinct modifier on a SPARQL Query
  29. /// </summary>
  30. public class Distinct
  31. : IUnaryOperator
  32. {
  33. private ISparqlAlgebra _pattern;
  34. private bool _trimTemporaryVariables = true;
  35. /// <summary>
  36. /// Creates a new Distinct Modifier
  37. /// </summary>
  38. /// <param name="pattern">Pattern</param>
  39. public Distinct(ISparqlAlgebra pattern)
  40. {
  41. this._pattern = pattern;
  42. }
  43. /// <summary>
  44. /// Creates a new Distinct Modifier
  45. /// </summary>
  46. /// <param name="algebra">Inner Algebra</param>
  47. /// <param name="ignoreTemporaryVariables">Whether to ignore temporary variables</param>
  48. public Distinct(ISparqlAlgebra algebra, bool ignoreTemporaryVariables)
  49. : this(algebra)
  50. {
  51. this._trimTemporaryVariables = !ignoreTemporaryVariables;
  52. }
  53. /// <summary>
  54. /// Evaluates the Distinct Modifier
  55. /// </summary>
  56. /// <param name="context">Evaluation Context</param>
  57. /// <returns></returns>
  58. public BaseMultiset Evaluate(SparqlEvaluationContext context)
  59. {
  60. context.InputMultiset = context.Evaluate(this._pattern);
  61. if (context.InputMultiset is IdentityMultiset || context.InputMultiset is NullMultiset)
  62. {
  63. context.OutputMultiset = context.InputMultiset;
  64. return context.OutputMultiset;
  65. }
  66. else
  67. {
  68. if (this._trimTemporaryVariables)
  69. {
  70. //Trim temporary variables
  71. context.InputMultiset.Trim();
  72. }
  73. //Apply distinctness
  74. context.OutputMultiset = new Multiset(context.InputMultiset.Variables);
  75. IEnumerable<ISet> sets = context.InputMultiset.Sets.Distinct();
  76. foreach (ISet s in sets)
  77. {
  78. context.OutputMultiset.Add(s.Copy());
  79. }
  80. return context.OutputMultiset;
  81. }
  82. }
  83. /// <summary>
  84. /// Gets the Variables used in the Algebra
  85. /// </summary>
  86. public IEnumerable<String> Variables
  87. {
  88. get
  89. {
  90. return this._pattern.Variables;
  91. }
  92. }
  93. /// <summary>
  94. /// Gets the Inner Algebra
  95. /// </summary>
  96. public ISparqlAlgebra InnerAlgebra
  97. {
  98. get
  99. {
  100. return this._pattern;
  101. }
  102. }
  103. /// <summary>
  104. /// Gets the String representation of the Algebra
  105. /// </summary>
  106. /// <returns></returns>
  107. public override string ToString()
  108. {
  109. return "Distinct(" + this._pattern.ToString() + ")";
  110. }
  111. /// <summary>
  112. /// Converts the Algebra back to a SPARQL Query
  113. /// </summary>
  114. /// <returns></returns>
  115. public SparqlQuery ToQuery()
  116. {
  117. SparqlQuery q = this._pattern.ToQuery();
  118. switch (q.QueryType)
  119. {
  120. case SparqlQueryType.Select:
  121. q.QueryType = SparqlQueryType.SelectDistinct;
  122. break;
  123. case SparqlQueryType.SelectAll:
  124. q.QueryType = SparqlQueryType.SelectAllDistinct;
  125. break;
  126. case SparqlQueryType.SelectAllDistinct:
  127. case SparqlQueryType.SelectAllReduced:
  128. case SparqlQueryType.SelectDistinct:
  129. case SparqlQueryType.SelectReduced:
  130. throw new NotSupportedException("Cannot convert a Distinct() to a SPARQL Query when the Inner Algebra converts to a Query that already has a DISTINCT/REDUCED modifier applied");
  131. case SparqlQueryType.Ask:
  132. case SparqlQueryType.Construct:
  133. case SparqlQueryType.Describe:
  134. case SparqlQueryType.DescribeAll:
  135. throw new NotSupportedException("Cannot convert a Distinct() to a SPARQL Query when the Inner Algebra converts to a Query that is not a SELECT query");
  136. case SparqlQueryType.Unknown:
  137. q.QueryType = SparqlQueryType.SelectDistinct;
  138. break;
  139. default:
  140. throw new NotSupportedException("Cannot convert a Distinct() to a SPARQL Query when the Inner Algebra converts to a Query with an unexpected Query Type");
  141. }
  142. return q;
  143. }
  144. /// <summary>
  145. /// Throws an exception since a Distinct() cannot be converted back to a Graph Pattern
  146. /// </summary>
  147. /// <returns></returns>
  148. /// <exception cref="NotSupportedException">Thrown since a Distinct() cannot be converted to a Graph Pattern</exception>
  149. public GraphPattern ToGraphPattern()
  150. {
  151. throw new NotSupportedException("A Distinct() cannot be converted to a GraphPattern");
  152. }
  153. /// <summary>
  154. /// Transforms the Inner Algebra using the given Optimiser
  155. /// </summary>
  156. /// <param name="optimiser">Optimiser</param>
  157. /// <returns></returns>
  158. public ISparqlAlgebra Transform(IAlgebraOptimiser optimiser)
  159. {
  160. return new Distinct(optimiser.Optimise(this._pattern));
  161. }
  162. }
  163. /// <summary>
  164. /// Represents a Reduced modifier on a SPARQL Query
  165. /// </summary>
  166. public class Reduced
  167. : IUnaryOperator
  168. {
  169. private ISparqlAlgebra _pattern;
  170. /// <summary>
  171. /// Creates a new Reduced Modifier
  172. /// </summary>
  173. /// <param name="pattern">Pattern</param>
  174. public Reduced(ISparqlAlgebra pattern)
  175. {
  176. this._pattern = pattern;
  177. }
  178. /// <summary>
  179. /// Evaluates the Reduced Modifier
  180. /// </summary>
  181. /// <param name="context">Evaluation Context</param>
  182. /// <returns></returns>
  183. public BaseMultiset Evaluate(SparqlEvaluationContext context)
  184. {
  185. context.InputMultiset = context.Evaluate(this._pattern);//this._pattern.Evaluate(context);
  186. if (context.InputMultiset is IdentityMultiset || context.InputMultiset is NullMultiset)
  187. {
  188. context.OutputMultiset = context.InputMultiset;
  189. return context.OutputMultiset;
  190. }
  191. else
  192. {
  193. if (context.Query.Limit > 0)
  194. {
  195. context.OutputMultiset = new Multiset(context.InputMultiset.Variables);
  196. foreach (ISet s in context.InputMultiset.Sets.Distinct())
  197. {
  198. context.OutputMultiset.Add(s.Copy());
  199. }
  200. }
  201. else
  202. {
  203. context.OutputMultiset = context.InputMultiset;
  204. }
  205. return context.OutputMultiset;
  206. }
  207. }
  208. /// <summary>
  209. /// Gets the Variables used in the Algebra
  210. /// </summary>
  211. public IEnumerable<String> Variables
  212. {
  213. get
  214. {
  215. return this._pattern.Variables.Distinct();
  216. }
  217. }
  218. /// <summary>
  219. /// Gets the Inner Algebra
  220. /// </summary>
  221. public ISparqlAlgebra InnerAlgebra
  222. {
  223. get
  224. {
  225. return this._pattern;
  226. }
  227. }
  228. /// <summary>
  229. /// Gets the String representation of the Algebra
  230. /// </summary>
  231. /// <returns></returns>
  232. public override string ToString()
  233. {
  234. return "Reduced(" + this._pattern.ToString() + ")";
  235. }
  236. /// <summary>
  237. /// Converts the Algebra back to a SPARQL Query
  238. /// </summary>
  239. /// <returns></returns>
  240. public SparqlQuery ToQuery()
  241. {
  242. SparqlQuery q = this._pattern.ToQuery();
  243. switch (q.QueryType)
  244. {
  245. case SparqlQueryType.Select:
  246. q.QueryType = SparqlQueryType.SelectReduced;
  247. break;
  248. case SparqlQueryType.SelectAll:
  249. q.QueryType = SparqlQueryType.SelectAllReduced;
  250. break;
  251. case SparqlQueryType.SelectAllDistinct:
  252. case SparqlQueryType.SelectAllReduced:
  253. case SparqlQueryType.SelectDistinct:
  254. case SparqlQueryType.SelectReduced:
  255. throw new NotSupportedException("Cannot convert a Reduced() to a SPARQL Query when the Inner Algebra converts to a Query that already has a DISTINCT/REDUCED modifier applied");
  256. case SparqlQueryType.Ask:
  257. case SparqlQueryType.Construct:
  258. case SparqlQueryType.Describe:
  259. case SparqlQueryType.DescribeAll:
  260. throw new NotSupportedException("Cannot convert a Reduced() to a SPARQL Query when the Inner Algebra converts to a Query that is not a SELECT query");
  261. case SparqlQueryType.Unknown:
  262. q.QueryType = SparqlQueryType.SelectReduced;
  263. break;
  264. default:
  265. throw new NotSupportedException("Cannot convert a Reduced() to a SPARQL Query when the Inner Algebra converts to a Query with an unexpected Query Type");
  266. }
  267. return q;
  268. }
  269. /// <summary>
  270. /// Throws an exception since a Reduced() cannot be converted back to a Graph Pattern
  271. /// </summary>
  272. /// <returns></returns>
  273. /// <exception cref="NotSupportedException">Thrown since a Reduced() cannot be converted to a Graph Pattern</exception>
  274. public GraphPattern ToGraphPattern()
  275. {
  276. throw new NotSupportedException("A Reduced() cannot be converted to a GraphPattern");
  277. }
  278. /// <summary>
  279. /// Transforms the Inner Algebra using the given Optimiser
  280. /// </summary>
  281. /// <param name="optimiser">Optimiser</param>
  282. /// <returns></returns>
  283. public ISparqlAlgebra Transform(IAlgebraOptimiser optimiser)
  284. {
  285. return new Reduced(optimiser.Optimise(this._pattern));
  286. }
  287. }
  288. }