-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
LazyMapEntry.java
206 lines (175 loc) · 6.19 KB
/
LazyMapEntry.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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
145
146
147
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
* Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.map.impl;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.internal.serialization.Data;
import com.hazelcast.internal.serialization.InternalSerializationService;
import com.hazelcast.map.ExtendedMapEntry;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.IdentifiedDataSerializable;
import com.hazelcast.query.impl.CachedQueryEntry;
import com.hazelcast.query.impl.Metadata;
import com.hazelcast.query.impl.getters.Extractors;
import static com.hazelcast.map.impl.record.Record.UNSET;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* A {@link java.util.Map.Entry Map.Entry} implementation
* which serializes/de-serializes key and value objects on
* demand. It is beneficial when you need to prevent unneeded
* serialization/de-serialization when creating a {@link
* java.util.Map.Entry Map.Entry}. Mainly targeted to supply a lazy entry
* to {@link com.hazelcast.map.EntryProcessor#process(Map.Entry)} method.
* <p>
* <STRONG>
* Note that this implementation is not
* synchronized and is not thread-safe.
* </STRONG>
* <p>
* LazyMapEntry itself is serializable as long as the object
* representations of both key and value are serializable.
* After serialization objects are resolved using injected
* SerializationService. De-serialized LazyMapEntry does
* contain object representation only Data representations
* and SerializationService is set to null. In other
* words: It's as usable just as a regular Map.Entry.
*
* @param <K> key
* @param <V> value
*/
public class LazyMapEntry<K, V> extends CachedQueryEntry<K, V>
implements Serializable, IdentifiedDataSerializable, ExtendedMapEntry<K, V> {
private static final long serialVersionUID = 0L;
private transient boolean modified;
private transient Metadata metadata;
private transient long newTtl = UNSET;
public LazyMapEntry() {
}
public LazyMapEntry(Data key, Object value, InternalSerializationService serializationService) {
this(key, value, serializationService, null);
}
public LazyMapEntry(Data key, Object value, InternalSerializationService serializationService, Extractors extractors) {
init(serializationService, key, value, extractors);
}
@Override
public LazyMapEntry init(InternalSerializationService serializationService, Data key, Object value, Extractors extractors) {
super.init(serializationService, key, value, extractors);
modified = false;
metadata = null;
return this;
}
public void setValueByInMemoryFormat(InMemoryFormat inMemoryFormat, Object value) {
if (inMemoryFormat == InMemoryFormat.OBJECT) {
valueObject = (V) value;
valueData = null;
} else {
valueData = (Data) value;
valueObject = null;
}
}
@Override
public V setValue(V value) {
modified = true;
V oldValue = getValue();
this.valueObject = value;
this.valueData = null;
return oldValue;
}
@Override
public V setValue(V value, long ttl, TimeUnit ttlUnit) {
newTtl = ttlUnit.toMillis(ttl);
return setValue(value);
}
/**
* Similar to calling {@link #setValue} with null but doesn't return old-value hence no extra deserialization.
*/
public void remove() {
modified = true;
valueObject = null;
valueData = null;
}
/**
* Checks if this entry has null value without any deserialization.
*
* @return true if value is null, otherwise returns false.
*/
public boolean hasNullValue() {
return valueObject == null && valueData == null;
}
public boolean isModified() {
return modified;
}
public long getNewTtl() {
return newTtl;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Map.Entry)) {
return false;
}
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
return Objects.equals(getKey(), e.getKey())
&& Objects.equals(getValue(), e.getValue());
}
@Override
public int hashCode() {
return (getKey() == null ? 0 : getKey().hashCode())
^ (getValue() == null ? 0 : getValue().hashCode());
}
@Override
public String toString() {
return getKey() + "=" + getValue();
}
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
keyObject = (K) in.readObject();
valueObject = (V) in.readObject();
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeObject(getKey());
out.writeObject(getValue());
}
@Override
public void readData(ObjectDataInput in) throws IOException {
keyObject = in.readObject();
valueObject = in.readObject();
}
@Override
public void writeData(ObjectDataOutput out) throws IOException {
out.writeObject(getKey());
out.writeObject(getValue());
}
@Override
public int getFactoryId() {
return MapDataSerializerHook.F_ID;
}
@Override
public int getClassId() {
return MapDataSerializerHook.LAZY_MAP_ENTRY;
}
public Metadata getMetadata() {
return metadata;
}
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
}
}