Skip to content

Commit

Permalink
delta record serialization implemented, equals method of delta docume…
Browse files Browse the repository at this point in the history
…nt used in unit tests implemented
  • Loading branch information
markodjurovic committed Jul 10, 2018
1 parent e839685 commit f5b2734
Show file tree
Hide file tree
Showing 9 changed files with 801 additions and 298 deletions.
Expand Up @@ -15,10 +15,24 @@
*/
package com.orientechnologies.orient.core.delta;

import com.orientechnologies.common.collection.OMultiValue;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.serialization.ODocumentSerializable;
import com.orientechnologies.orient.core.serialization.OSerializableStream;
import com.orientechnologies.orient.core.serialization.serializer.record.binary.BytesContainer;
import com.orientechnologies.orient.core.serialization.serializer.record.binary.OSerializableWrapper;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
*
Expand Down Expand Up @@ -57,4 +71,265 @@ public void deserialize(BytesContainer bytes){

}

public boolean isLeaf(){
return fields.isEmpty();
}

public Set<Map.Entry<String, Object>> fields(){
return fields.entrySet();
}

private static boolean equalDocsInThisContext(ODocument doc1, ODocument doc2){

String[] fieldNames = doc1.fieldNames();

for (String fieldName : fieldNames){
if (!doc2.containsField(fieldName)){
return false;
}
Object fieldVal = doc1.field(fieldName);
Object otherFieldVal = doc2.field(fieldName);

if (!equalVals(fieldVal, otherFieldVal)){
return false;
}
}

return true;
}

private static boolean equalEmbeddedCollections(Collection<Object> col1, Collection<Object> col2){
if (col1.size() != col2.size()){
return false;
}

if (col1 instanceof List){
List<Object> l1 = (List<Object>)col1;
List<Object> l2 = (List<Object>)col2;
for (int i = 0; i < l1.size(); i++){
Object o1 = l1.get(i);
Object o2 = l2.get(i);

if (!equalVals(o1, o2)){
return false;
}
}
}
else{
Set<Object> s1 = (Set<Object>)col1;
//create new set because of remove
Set<Object> s2 = new HashSet<>(col2);

for (Object o1 : s1){
boolean foundInOther = false;

Iterator<Object> iter2 = s2.iterator();
while (iter2.hasNext()){
Object o2 = iter2.next();

if (equalVals(o1, o2)){
foundInOther = true;
iter2.remove();
}
}

if (!foundInOther){
return false;
}
}

}
return true;
}

private static boolean equalEmbeddedMaps(Map<String, Object> m1, Map<String, Object> m2){
if (m1.size() != m2.size()){
return false;
}

for (Map.Entry<String, Object> entry : m1.entrySet()){
String fieldName = entry.getKey();
if (!m2.containsKey(fieldName)){
return false;
}

Object fieldVal = entry.getValue();
Object otherFieldVal = m2.get(fieldName);

if (!equalVals(fieldVal, otherFieldVal)){
return false;
}
}

return true;
}

private static boolean equalVals(Object val1, Object val2){
if (val1 == val2){
return true;
}

if ((val1 == null && val2 != null) ||
(val1 != null && val2 == null)){
return false;
}

if (val1 == null && val2 == null){
return true;
}

OType fieldType = OType.getTypeByClass(val1.getClass());
if (fieldType == OType.LINK && val1 instanceof ODocument){
fieldType = OType.EMBEDDED;
}
OType otherFieldType = OType.getTypeByClass(val2.getClass());
if (otherFieldType == OType.LINK && val2 instanceof ODocument){
otherFieldType = OType.EMBEDDED;
}

if (fieldType != otherFieldType){
return false;
}

switch (fieldType) {
case INTEGER:
case LONG:
case SHORT:
case STRING:
case DOUBLE:
case FLOAT:
case BYTE:
case BOOLEAN:
case DATETIME:
case DATE:
case LINKBAG:
case BINARY:
case DECIMAL:
case LINKSET:
case LINKLIST:
case DELTA_RECORD:
case LINK:
case LINKMAP:
case TRANSIENT:
case ANY:

if (!Objects.equals(val1, val2)){
return false;
}

break;
case EMBEDDED:
ODocument fieldDoc;
if (val1 instanceof ODocumentSerializable) {
fieldDoc = ((ODocumentSerializable) val1).toDocument();
} else {
fieldDoc = (ODocument) val1;
}

ODocument otherFieldDoc;
if (val2 instanceof ODocumentSerializable) {
otherFieldDoc = ((ODocumentSerializable) val2).toDocument();
} else {
otherFieldDoc = (ODocument) val2;
}

if (!equalDocsInThisContext(fieldDoc, otherFieldDoc)){
return false;
}

break;
case EMBEDDEDSET:
case EMBEDDEDLIST:
Collection col1;
if (val1.getClass().isArray())
col1 = Arrays.asList(OMultiValue.array(val1));
else
col1 = (Collection) val1;

Collection col2;
if (val2.getClass().isArray())
col2 = Arrays.asList(OMultiValue.array(val2));
else
col2 = (Collection) val2;

if (!equalEmbeddedCollections(col1, col2)){
return false;
}
break;
case EMBEDDEDMAP:
Map m1 = (Map)val1;
Map m2 = (Map)val2;
if (!equalEmbeddedMaps(m1, m2)){
return false;
}
break;
case CUSTOM:
byte[] v1;
if (!(val1 instanceof OSerializableStream)){
v1 = new OSerializableWrapper((Serializable) val1).toStream();
}
else{
v1 = ((OSerializableStream)val1).toStream();
}

byte[] v2;
if (!(val2 instanceof OSerializableStream)){
v2 = new OSerializableWrapper((Serializable) val2).toStream();
}
else{
v2 = ((OSerializableStream)val2).toStream();
}

if (!Objects.equals(v1, v2)){
return false;
}
break;
}

return true;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ODocumentDelta other = (ODocumentDelta) obj;

if (fields.size() != other.fields.size()){
return false;
}

for (Map.Entry<String, Object> field : fields.entrySet()){
String fieldName = field.getKey();
if (!other.fields.containsKey(fieldName)){
return false;
}

Object fieldVal = field.getValue();
Object otherFieldVal = other.fields.get(fieldName);

if (!equalVals(fieldVal, otherFieldVal)){
return false;
}
}

return true;
}

@Override
public int hashCode() {
int hash = 7;
hash = 67 * hash + Objects.hashCode(this.fields);
return hash;
}



}
Expand Up @@ -25,5 +25,5 @@ public interface ODocumentDeltaSerializer {

byte[] toStream(ODocumentDelta delta);

void fromStream(BytesContainer bytes, ODocumentDelta toDoc);
ODocumentDelta fromStream(BytesContainer bytes);
}

This file was deleted.

0 comments on commit f5b2734

Please sign in to comment.