edge.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. /*
  11. Package data contains classes and functions to handle graph data.
  12. Nodes
  13. Nodes are items stored in the graph. The graphNode object is the minimal
  14. implementation of the Node interface and represents a simple node. Setting a
  15. nil value to an attribute is equivalent to removing the attribute. An attribute
  16. value can be any object which can be serialized by gob.
  17. Edges
  18. Edges are items stored in the graph. Edges connect nodes. The graphEdge object
  19. is the minimal implementation of the Edge interface and represents a simple edge.
  20. Setting a nil value to an attribute is equivalent to removing the attribute. An
  21. attribute value can be any object which can be serialized by gob.
  22. */
  23. package data
  24. import "fmt"
  25. /*
  26. Edge models edges in the graph
  27. */
  28. type Edge interface {
  29. Node
  30. /*
  31. End1Key returns the key of the first end of this edge.
  32. */
  33. End1Key() string
  34. /*
  35. End1Kind returns the kind of the first end of this edge.
  36. */
  37. End1Kind() string
  38. /*
  39. End1Role returns the role of the first end of this edge.
  40. */
  41. End1Role() string
  42. /*
  43. End1IsCascading is a flag to indicate that delete operations from this
  44. end are cascaded to the other end.
  45. */
  46. End1IsCascading() bool
  47. /*
  48. End1IsCascadingLast is a flag to indicate that cascading delete
  49. operations are only executed if this is the last/only edge of
  50. this kind to the other end. The flag is ignored if End1IsCascading is
  51. false.
  52. */
  53. End1IsCascadingLast() bool
  54. /*
  55. End2Key returns the key of the second end of this edge.
  56. */
  57. End2Key() string
  58. /*
  59. End2Kind returns the kind of the second end of this edge.
  60. */
  61. End2Kind() string
  62. /*
  63. End2Role returns the role of the second end of this edge.
  64. */
  65. End2Role() string
  66. /*
  67. End2IsCascading is a flag to indicate that delete operations from this
  68. end are cascaded to the other end.
  69. */
  70. End2IsCascading() bool
  71. /*
  72. End2IsCascadingLast is a flag to indicate that cascading delete
  73. operations are only executed if this is the last/only edge of
  74. this kind to the other end. The flag is ignored if End2IsCascading is
  75. false.
  76. */
  77. End2IsCascadingLast() bool
  78. /*
  79. Spec returns the spec for this edge from the view of a specified endpoint.
  80. A spec is always of the form: <End Role>:<Kind>:<End Role>:<Other node kind>
  81. */
  82. Spec(key string) string
  83. /*
  84. OtherEndKey returns the key of the endpoint which is on the other side
  85. from the given key.
  86. */
  87. OtherEndKey(key string) string
  88. /*
  89. OtherEndKind returns the kind of the endpoint which is on the other side
  90. from the given key.
  91. */
  92. OtherEndKind(key string) string
  93. }
  94. /*
  95. EdgeEnd1Key is the key of the first end
  96. */
  97. const EdgeEnd1Key = "end1key"
  98. /*
  99. EdgeEnd1Kind is the kind of the first end
  100. */
  101. const EdgeEnd1Kind = "end1kind"
  102. /*
  103. EdgeEnd1Role is the role of the first end
  104. */
  105. const EdgeEnd1Role = "end1role"
  106. /*
  107. EdgeEnd1Cascading is the flag to cascade delete operations from the first end
  108. */
  109. const EdgeEnd1Cascading = "end1cascading"
  110. /*
  111. EdgeEnd1CascadingLast is a flag to indicate that cascading delete
  112. operations are only executed on the last/only edge of
  113. a kind
  114. */
  115. const EdgeEnd1CascadingLast = "end1cascadinglast"
  116. /*
  117. EdgeEnd2Key is the key of the second end
  118. */
  119. const EdgeEnd2Key = "end2key"
  120. /*
  121. EdgeEnd2Kind is the kind of the second end
  122. */
  123. const EdgeEnd2Kind = "end2kind"
  124. /*
  125. EdgeEnd2Role is the role of the second end
  126. */
  127. const EdgeEnd2Role = "end2role"
  128. /*
  129. EdgeEnd2Cascading is the flag to cascade delete operations from the second end
  130. */
  131. const EdgeEnd2Cascading = "end2cascading"
  132. /*
  133. EdgeEnd2CascadingLast is a flag to indicate that cascading delete
  134. operations are only executed on the last/only edge of
  135. a kind
  136. */
  137. const EdgeEnd2CascadingLast = "end2cascadinglast"
  138. /*
  139. graphEdge data structure.
  140. */
  141. type graphEdge struct {
  142. *graphNode
  143. }
  144. /*
  145. NewGraphEdge creates a new Edge instance.
  146. */
  147. func NewGraphEdge() Edge {
  148. return &graphEdge{&graphNode{make(map[string]interface{})}}
  149. }
  150. /*
  151. NewGraphEdgeFromNode creates a new Edge instance.
  152. */
  153. func NewGraphEdgeFromNode(node Node) Edge {
  154. if node == nil {
  155. return nil
  156. }
  157. return &graphEdge{&graphNode{node.Data()}}
  158. }
  159. /*
  160. End1Key returns the key of the first end of this edge.
  161. */
  162. func (ge *graphEdge) End1Key() string {
  163. return ge.stringAttr(EdgeEnd1Key)
  164. }
  165. /*
  166. End1Kind returns the kind of the first end of this edge.
  167. */
  168. func (ge *graphEdge) End1Kind() string {
  169. return ge.stringAttr(EdgeEnd1Kind)
  170. }
  171. /*
  172. End1Role returns the role of the first end of this edge.
  173. */
  174. func (ge *graphEdge) End1Role() string {
  175. return ge.stringAttr(EdgeEnd1Role)
  176. }
  177. /*
  178. End1IsCascading is a flag to indicate that delete operations from this
  179. end are cascaded to the other end.
  180. */
  181. func (ge *graphEdge) End1IsCascading() bool {
  182. return ge.Attr(EdgeEnd1Cascading).(bool)
  183. }
  184. /*
  185. End1IsCascadingLast is a flag to indicate that cascading delete
  186. operations are only executed if this is the last/only edge of
  187. this kind to the other end. The flag is ignored if End1IsCascading is
  188. false.
  189. */
  190. func (ge *graphEdge) End1IsCascadingLast() bool {
  191. a := ge.Attr(EdgeEnd1CascadingLast)
  192. return a != nil && a.(bool)
  193. }
  194. /*
  195. End2Key returns the key of the second end of this edge.
  196. */
  197. func (ge *graphEdge) End2Key() string {
  198. return ge.stringAttr(EdgeEnd2Key)
  199. }
  200. /*
  201. End2Kind returns the kind of the second end of this edge.
  202. */
  203. func (ge *graphEdge) End2Kind() string {
  204. return ge.stringAttr(EdgeEnd2Kind)
  205. }
  206. /*
  207. End2Role returns the role of the second end of this edge.
  208. */
  209. func (ge *graphEdge) End2Role() string {
  210. return ge.stringAttr(EdgeEnd2Role)
  211. }
  212. /*
  213. End2IsCascading is a flag to indicate that delete operations from this
  214. end are cascaded to the other end.
  215. */
  216. func (ge *graphEdge) End2IsCascading() bool {
  217. return ge.Attr(EdgeEnd2Cascading).(bool)
  218. }
  219. /*
  220. End2IsCascadingLast is a flag to indicate that cascading delete
  221. operations are only executed if this is the last/only edge of
  222. this kind to the other end. The flag is ignored if End2IsCascading is
  223. false.
  224. */
  225. func (ge *graphEdge) End2IsCascadingLast() bool {
  226. a := ge.Attr(EdgeEnd2CascadingLast)
  227. return a != nil && a.(bool)
  228. }
  229. /*
  230. Spec returns the spec for this edge from the view of a specified endpoint.
  231. A spec is always of the form: <End Role>:<Kind>:<End Role>:<Other node kind>
  232. */
  233. func (ge *graphEdge) Spec(key string) string {
  234. if key == ge.End1Key() {
  235. return fmt.Sprintf("%s:%s:%s:%s", ge.End1Role(), ge.Kind(), ge.End2Role(), ge.End2Kind())
  236. } else if key == ge.End2Key() {
  237. return fmt.Sprintf("%s:%s:%s:%s", ge.End2Role(), ge.Kind(), ge.End1Role(), ge.End1Kind())
  238. }
  239. return ""
  240. }
  241. /*
  242. OtherEndKey returns the key of the endpoint which is on the other side
  243. from the given key.
  244. */
  245. func (ge *graphEdge) OtherEndKey(key string) string {
  246. if key == ge.End1Key() {
  247. return ge.End2Key()
  248. } else if key == ge.End2Key() {
  249. return ge.End1Key()
  250. }
  251. return ""
  252. }
  253. /*
  254. OtherEndKind returns the kind of the endpoint which is on the other side
  255. from the given key.
  256. */
  257. func (ge *graphEdge) OtherEndKind(key string) string {
  258. if key == ge.End1Key() {
  259. return ge.End2Kind()
  260. } else if key == ge.End2Key() {
  261. return ge.End1Kind()
  262. }
  263. return ""
  264. }
  265. /*
  266. IndexMap returns a representation of this node as a string map which
  267. can be used to provide a full-text search.
  268. */
  269. func (ge *graphEdge) IndexMap() map[string]string {
  270. return createIndexMap(ge.graphNode, func(attr string) bool {
  271. return attr == NodeKey || attr == NodeKind || attr == EdgeEnd1Key ||
  272. attr == EdgeEnd1Kind || attr == EdgeEnd1Role ||
  273. attr == EdgeEnd1Cascading || attr == EdgeEnd1CascadingLast ||
  274. attr == EdgeEnd2Key || attr == EdgeEnd2Kind || attr == EdgeEnd2Role ||
  275. attr == EdgeEnd2Cascading || attr == EdgeEnd2CascadingLast
  276. })
  277. }
  278. /*
  279. String returns a string representation of this edge.
  280. */
  281. func (ge *graphEdge) String() string {
  282. return dataToString("GraphEdge", ge.graphNode)
  283. }