2
2
3
3
import io .hgraphdb .models .EdgeIndexModel ;
4
4
import io .hgraphdb .models .EdgeModel ;
5
+ import io .hgraphdb .mutators .Mutator ;
6
+ import io .hgraphdb .mutators .Mutators ;
7
+
5
8
import org .apache .tinkerpop .gremlin .structure .Direction ;
6
9
import org .apache .tinkerpop .gremlin .structure .Edge ;
7
10
import org .apache .tinkerpop .gremlin .structure .Property ;
12
15
import org .slf4j .Logger ;
13
16
import org .slf4j .LoggerFactory ;
14
17
18
+ import java .util .Collections ;
15
19
import java .util .Iterator ;
16
20
import java .util .Map ;
21
+ import java .util .Set ;
22
+ import java .util .Map .Entry ;
23
+ import java .util .concurrent .ConcurrentHashMap ;
24
+ import java .util .stream .Stream ;
17
25
18
26
public class HBaseEdge extends HBaseElement implements Edge {
19
27
20
28
private static final Logger LOGGER = LoggerFactory .getLogger (HBaseEdge .class );
21
29
22
30
private Vertex inVertex ;
23
31
private Vertex outVertex ;
32
+ protected Map <String , Object > properties ;
33
+ protected transient boolean propertiesFullyLoaded ;
24
34
25
35
public HBaseEdge (HBaseGraph graph , Object id ) {
26
36
this (graph , id , null , null , null , null , null , null );
@@ -37,10 +47,12 @@ public HBaseEdge(HBaseGraph graph, Object id, String label, Long createdAt, Long
37
47
38
48
public HBaseEdge (HBaseGraph graph , Object id , String label , Long createdAt , Long updatedAt , Map <String , Object > properties ,
39
49
boolean propertiesFullyLoaded , Vertex inVertex , Vertex outVertex ) {
40
- super (graph , id , label , createdAt , updatedAt , properties , propertiesFullyLoaded );
50
+ super (graph , id , label , createdAt , updatedAt );
41
51
42
52
this .inVertex = inVertex ;
43
53
this .outVertex = outVertex ;
54
+ this .properties = properties ;
55
+ this .propertiesFullyLoaded = propertiesFullyLoaded ;
44
56
}
45
57
46
58
@ Override
@@ -55,13 +67,26 @@ public ElementType getElementType() {
55
67
return ElementType .EDGE ;
56
68
}
57
69
70
+ public Map <String , Object > getProperties () {
71
+ if (properties == null || !propertiesFullyLoaded ) {
72
+ load ();
73
+ propertiesFullyLoaded = true ;
74
+ }
75
+ return properties ;
76
+ }
77
+
58
78
@ Override
59
79
public void copyFrom (HBaseElement element ) {
60
80
super .copyFrom (element );
61
81
if (element instanceof HBaseEdge ) {
62
82
HBaseEdge copy = (HBaseEdge ) element ;
63
83
if (copy .inVertex != null ) this .inVertex = copy .inVertex ;
64
84
if (copy .outVertex != null ) this .outVertex = copy .outVertex ;
85
+ if (copy .properties != null
86
+ && (copy .propertiesFullyLoaded || this .properties == null )) {
87
+ this .properties = new ConcurrentHashMap <>(copy .properties );
88
+ this .propertiesFullyLoaded = copy .propertiesFullyLoaded ;
89
+ }
65
90
}
66
91
}
67
92
@@ -100,6 +125,101 @@ public Vertex getVertex(Direction direction) throws IllegalArgumentException {
100
125
return Direction .IN .equals (direction ) ? inVertex : outVertex ;
101
126
}
102
127
128
+ public void setProperty (String key , Object value ) {
129
+ ElementHelper .validateProperty (key , value );
130
+
131
+ graph .validateProperty (getElementType (), label , key , value );
132
+
133
+ // delete from index model before setting property
134
+ Object oldValue = null ;
135
+ boolean hasIndex = hasIndex (OperationType .WRITE , key );
136
+ if (hasIndex ) {
137
+ // only load old value if using index
138
+ oldValue = getProperty (key );
139
+ if (oldValue != null && !oldValue .equals (value )) {
140
+ deleteFromIndexModel (key , null );
141
+ }
142
+ }
143
+
144
+ getProperties ().put (key , value );
145
+ updatedAt (System .currentTimeMillis ());
146
+
147
+ if (hasIndex ) {
148
+ if (oldValue == null || !oldValue .equals (value )) {
149
+ writeToIndexModel (key );
150
+ }
151
+ }
152
+ Mutator writer = getModel ().writeProperty (this , key , value );
153
+ Mutators .write (getTable (), writer );
154
+ }
155
+
156
+ public void incrementProperty (String key , long value ) {
157
+ if (!graph .configuration ().getUseSchema ()) {
158
+ throw new HBaseGraphNoSchemaException ("Schema not enabled" );
159
+ }
160
+ ElementHelper .validateProperty (key , value );
161
+
162
+ graph .validateProperty (getElementType (), label , key , value );
163
+
164
+ updatedAt (System .currentTimeMillis ());
165
+
166
+ Mutator writer = getModel ().incrementProperty (this , key , value );
167
+ long newValue = Mutators .increment (getTable (), writer , key );
168
+ getProperties ().put (key , newValue );
169
+ }
170
+
171
+ @ Override
172
+ public Set <String > keys () {
173
+ return Collections .unmodifiableSet (properties .keySet ());
174
+ }
175
+
176
+ public void removeProperty (String key ) {
177
+ Object value = getProperty (key );
178
+ if (value != null ) {
179
+ // delete from index model before removing property
180
+ boolean hasIndex = hasIndex (OperationType .WRITE , key );
181
+ if (hasIndex ) {
182
+ deleteFromIndexModel (key , null );
183
+ }
184
+
185
+ getProperties ().remove (key );
186
+ updatedAt (System .currentTimeMillis ());
187
+
188
+ Mutator writer = getModel ().clearProperty (this , key );
189
+ Mutators .write (getTable (), writer );
190
+ }
191
+ }
192
+
193
+ @ Override
194
+ public Stream <Entry <String , Object >> propertyEntriesStream () {
195
+ return properties .entrySet ().stream ();
196
+ }
197
+
198
+ @ Override
199
+ public int propertySize () {
200
+ return this .properties .size ();
201
+ }
202
+
203
+ @ SuppressWarnings ("unchecked" )
204
+ public <V > V getProperty (String key ) {
205
+ if (properties != null ) {
206
+ // optimization for partially loaded properties
207
+ V val = (V ) properties .get (key );
208
+ if (val != null ) return val ;
209
+ }
210
+ return (V ) getProperties ().get (key );
211
+ }
212
+
213
+ @ Override
214
+ public boolean hasProperty (String key ) {
215
+ if (properties != null ) {
216
+ // optimization for partially loaded properties
217
+ Object val = properties .get (key );
218
+ if (val != null ) return true ;
219
+ }
220
+ return keys ().contains (key );
221
+ }
222
+
103
223
@ Override
104
224
public void remove () {
105
225
// Get rid of the endpoints and edge themselves.
@@ -115,7 +235,7 @@ public void remove() {
115
235
116
236
@ Override
117
237
public <V > Iterator <Property <V >> properties (final String ... propertyKeys ) {
118
- Iterable <String > keys = getPropertyKeys ();
238
+ Iterable <String > keys = keys ();
119
239
Iterator <String > filter = IteratorUtils .filter (keys .iterator (),
120
240
key -> ElementHelper .keyExists (key , propertyKeys ));
121
241
return IteratorUtils .map (filter ,
0 commit comments