Class: Agama::Graph
- Inherits:
-
Object
- Object
- Agama::Graph
- Defined in:
- lib/agama/graph.rb
Instance Method Summary collapse
- #clean_edge(edge) ⇒ Object
-
#clean_node(node) ⇒ Object
Methods to seperate key from the value.
-
#close ⇒ Object
Closes the database connection.
- #edge_count(type = nil) ⇒ Object
-
#get_edge(edge) ⇒ Object
Fetches the value assigned to the edge from the from node to the to node.
-
#get_node(node) ⇒ Object
Fetches the node requested.
-
#initialize(params) ⇒ Graph
constructor
Initialises variables and sets the path.
- #neighbours(node) ⇒ Object
-
#node_count(type = nil) ⇒ Object
Accessors for meta values.
-
#open ⇒ Object
Opens the database for access.
-
#set_edge(edge) ⇒ Object
Creates/Updates an edge.
-
#set_node(node) ⇒ Object
Creates/Updates a node.
Constructor Details
#initialize(params) ⇒ Graph
Initialises variables and sets the path
6 7 8 9 |
# File 'lib/agama/graph.rb', line 6 def initialize(params) @db_path = params[:path] || "./" @db = params[:db] end |
Instance Method Details
#clean_edge(edge) ⇒ Object
254 255 256 257 258 259 260 261 262 |
# File 'lib/agama/graph.rb', line 254 def clean_edge(edge) new_edge = {} edge.each do |key, value| next if (key == :type or key == :from or key == :to or key == :directed) new_edge[key] = value end return new_edge end |
#clean_node(node) ⇒ Object
Methods to seperate key from the value
244 245 246 247 248 249 250 251 252 |
# File 'lib/agama/graph.rb', line 244 def clean_node(node) new_node = {} node.each do |key, value| next if (key == :type or key == :name) new_node[key] = value end return new_node end |
#close ⇒ Object
Closes the database connection
29 30 31 |
# File 'lib/agama/graph.rb', line 29 def close @db.close end |
#edge_count(type = nil) ⇒ Object
230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/agama/graph.rb', line 230 def edge_count(type = nil) if type value = @db.m_get("edge#{type}") if value etype = Marshal.load(value) etype[:count] end else Marshal.load(@db.m_get("m")) end end |
#get_edge(edge) ⇒ Object
Fetches the value assigned to the edge from the from node to the to node
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/agama/graph.rb', line 148 def get_edge(edge) return nil unless edge[:from][:name] return nil unless edge[:to][:name] #Get the type of the edge type = edge[:type] || Config::DEFAULT_TYPE edge[:type] = type #Check if the edge type exists etype = Marshal.load(@db.m_get("edge#{type}")) if @db.m_get("edge#{type}") #Integrity check: Check whether the edge direction is not contradictory if edge[:directed] if etype if etype[:directed] != edge[:directed] return false end else #If there is no edge of that type then pre-empt the result return false end else if etype edge[:directed] = etype[:directed] else #If there is no edge of that type then pre-empt the result return false end end #Convert the edge into a Key string and fetch the corresponding data key, reverse_key = Keyify.edge(edge) value = @db.e_get(key) if value new_edge = Marshal.load(value) new_edge[:from] = self.get_node(edge[:from]) new_edge[:to] = self.get_node(edge[:to]) new_edge[:type] = edge[:type] new_edge[:directed] = etype[:directed] #Pick direction alone from the meta_db for consistency new_edge end end |
#get_node(node) ⇒ Object
Fetches the node requested
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/agama/graph.rb', line 71 def get_node(node) return nil unless node[:name] #Convert the node into a Key string and fetch the corresponding data key = Keyify.node(node) value = @db.n_get(key) if value new_node = Marshal.load(value) new_node[:name] = node[:name] new_node[:type] = node[:type] || Config::DEFAULT_TYPE new_node end end |
#neighbours(node) ⇒ Object
192 193 194 195 |
# File 'lib/agama/graph.rb', line 192 def neighbours(node) traverser = Traverser.new(@db, self) traverser.set(:from => node) end |
#node_count(type = nil) ⇒ Object
Accessors for meta values
219 220 221 222 223 224 225 226 227 228 |
# File 'lib/agama/graph.rb', line 219 def node_count(type = nil) if type value = @db.m_get("node#{type}") if value Marshal.load(value) end else Marshal.load(@db.m_get("n")) end end |
#open ⇒ Object
Opens the database for access
13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/agama/graph.rb', line 13 def open @db.open(@db_path) #Create meta variables if they are absent unless @db.m_get("n") @db.m_put("n", Marshal.dump(0)) #Total node count @db.m_put("m", Marshal.dump(0)) #Total edge count @db.m_put("node#{Config::DEFAULT_TYPE}", Marshal.dump(0)) #Node count for default type @db.m_put("edge#{Config::DEFAULT_TYPE}", Marshal.dump({:directed => false, :count => 0})) #Edge count for default type end end |
#set_edge(edge) ⇒ Object
Creates/Updates an edge
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/agama/graph.rb', line 88 def set_edge(edge) return false unless edge return false unless edge[:from][:name] return false unless edge[:to][:name] #Get the type of the edge type = edge[:type] || Config::DEFAULT_TYPE edge[:type] = type #Check if the edge type exists etype = Marshal.load(@db.m_get("edge#{type}")) if @db.m_get("edge#{type}") #Integrity check: Check whether the edge direction is not contradictory if edge[:directed] if etype if etype[:directed] != edge[:directed] raise "Edge creation error: edge direction contradicting existing edges" return end end else if etype edge[:directed] = etype[:directed] else edge[:directed] = false end end #Convert the edge into Key, Reversed Key and Value strings for storage key, reverse_key = Keyify.edge(edge) value = Marshal.dump(clean_edge(edge)) #Integrity check: Check if the incident nodes are defined unless (self.get_node(edge[:from]) and self.get_node(edge[:to])) raise "Edge creation error: node(s) not defined" return end #Check whether the operation is an insert (not an update), if so increment count unless @db.e_get(key) if etype etype[:count] += 1 @db.m_put("edge#{type}", Marshal.dump(etype)) else @db.m_put("edge#{type}", Marshal.dump({:directed => edge[:directed], :count => 1})) end #Increment global count @db.m_put("m", Marshal.dump(Marshal.load(@db.m_get("m")) + 1)) end #Add the edge and the reversed edge if @db.e_put(key, value) and @db.e_put(reverse_key, value) return edge end end |
#set_node(node) ⇒ Object
Creates/Updates a node
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/agama/graph.rb', line 35 def set_node(node) return nil unless node[:name] #Get the type of the node type = node[:type] || Config::DEFAULT_TYPE node[:type] = type #Convert the node into Key and Value strings for storage key = Keyify.node(node) value = Marshal.dump(self.clean_node(node)) #remove key items from value #Check if the node type exists, and if so get its count count = Marshal.load(@db.m_get("node#{type}")) if @db.m_get("node#{type}") #Check whether the operation is an insert (not an update), if so increment count unless @db.n_get(key) #Increment type-specific count if count count += 1 @db.m_put("node#{type}", Marshal.dump(count)) else @db.m_put("node#{type}", Marshal.dump(1)) end #Increment global count @db.m_put("n", Marshal.dump(Marshal.load(@db.m_get("n")) + 1)) end #Store the node if @db.n_put(key, value) node end end |