Project

General

Profile

1
package eu.dnetlib.data.mapreduce.hbase.dedup;
2

    
3
import java.io.IOException;
4
import java.nio.ByteBuffer;
5
import java.util.Map;
6

    
7
import com.google.protobuf.InvalidProtocolBufferException;
8
import eu.dnetlib.data.mapreduce.JobParams;
9
import eu.dnetlib.data.mapreduce.util.DedupUtils;
10
import eu.dnetlib.data.proto.DedupProtos.Dedup;
11
import eu.dnetlib.data.proto.KindProtos.Kind;
12
import eu.dnetlib.data.proto.OafProtos.Oaf;
13
import eu.dnetlib.data.proto.OafProtos.OafRel.Builder;
14
import eu.dnetlib.data.proto.TypeProtos.Type;
15
import eu.dnetlib.data.transform.xml.AbstractDNetXsltFunctions;
16
import eu.dnetlib.pace.config.DedupConfig;
17
import org.apache.hadoop.hbase.client.Durability;
18
import org.apache.hadoop.hbase.client.Put;
19
import org.apache.hadoop.hbase.client.Result;
20
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
21
import org.apache.hadoop.hbase.mapreduce.TableMapper;
22
import org.apache.hadoop.hbase.util.Bytes;
23

    
24
public class DedupFindRootsMapper extends TableMapper<ImmutableBytesWritable, Put> {
25

    
26
	private DedupConfig dedupConf;
27

    
28
	@Override
29
	protected void setup(final Context context) throws IOException, InterruptedException {
30
		dedupConf = DedupConfig.load(context.getConfiguration().get(JobParams.DEDUP_CONF));
31
		System.out.println("dedup findRoots mapper\nwf conf: " + dedupConf.toString());
32
	}
33

    
34
	@Override
35
	protected void map(final ImmutableBytesWritable rowkey, final Result value, final Context context) throws IOException, InterruptedException {
36
		// System.out.println("Find root mapping: " + new String(rowkey.copyBytes()));
37

    
38
		final Type type = Type.valueOf(dedupConf.getWf().getEntityType());
39
		final Map<byte[], byte[]> similarRels = value.getFamilyMap(DedupUtils.getSimilarityCFBytes(type));
40

    
41
		if ((similarRels != null) && !similarRels.isEmpty()) {
42
			final ByteBuffer min = findMin(ByteBuffer.wrap(rowkey.get()), similarRels.keySet());
43

    
44
			final byte[] row = rowkey.copyBytes();
45
			final byte[] root = DedupUtils.newIdBytes(min, dedupConf.getWf().getDedupRun());
46

    
47
			// System.out.println("Found root: " + new String(root));
48

    
49
			emitDedupRel(context, DedupUtils.getDedupCF_mergedInBytes(type), row, root, buildRel(row, root, Dedup.RelName.isMergedIn));
50
			emitDedupRel(context, DedupUtils.getDedupCF_mergesBytes(type), root, row, buildRel(root, row, Dedup.RelName.merges));
51

    
52
			context.getCounter(dedupConf.getWf().getEntityType(), "dedupRel (x2)").increment(1);
53

    
54
			// marks the original body deleted
55
			emitBody(context, row, value.getValue(Bytes.toBytes(dedupConf.getWf().getEntityType()), DedupUtils.BODY_B));
56

    
57
		} else {
58
			context.getCounter(dedupConf.getWf().getEntityType(), "row not in similarity mesh").increment(1);
59
		}
60
	}
61

    
62
	private ByteBuffer findMin(ByteBuffer min, final Iterable<byte[]> keys) {
63
		for (final byte[] q : keys) {
64
			final ByteBuffer iq = ByteBuffer.wrap(q);
65
			if (min.compareTo(iq) > 0) {
66
				min = iq;
67
			}
68
		}
69
		return min;
70
	}
71

    
72
	private void emitBody(final Context context, final byte[] row, final byte[] body) throws InvalidProtocolBufferException, IOException, InterruptedException {
73
		if (body == null) {
74
			context.getCounter(dedupConf.getWf().getEntityType(), "missing body").increment(1);
75
			System.err.println("missing body: " + new String(row));
76
			return;
77
		}
78
		final Oaf prototype = Oaf.parseFrom(body);
79

    
80
		if (prototype.getDataInfo().getDeletedbyinference()) {
81
			context.getCounter(dedupConf.getWf().getEntityType(), "bodies already deleted").increment(1);
82
		} else {
83
			final Oaf.Builder oafRoot = Oaf.newBuilder(prototype);
84
			oafRoot.getDataInfoBuilder().setDeletedbyinference(true).setInferred(true).setInferenceprovenance(dedupConf.getWf().getConfigurationId());
85
			final byte[] family = Bytes.toBytes(dedupConf.getWf().getEntityType());
86
			final Put put = new Put(row).add(family, DedupUtils.BODY_B, oafRoot.build().toByteArray());
87
			put.setDurability(Durability.USE_DEFAULT);
88
			context.write(new ImmutableBytesWritable(row), put);
89
			context.getCounter(dedupConf.getWf().getEntityType(), "bodies marked deleted").increment(1);
90
		}
91
	}
92

    
93
	private byte[] buildRel(final byte[] from, final byte[] to, final Dedup.RelName relClass) {
94
		final Builder oafRel = DedupUtils.getDedup(dedupConf, new String(from), new String(to), relClass);
95
		final Oaf oaf =
96
				Oaf.newBuilder()
97
						.setKind(Kind.relation)
98
						.setLastupdatetimestamp(System.currentTimeMillis())
99
						.setDataInfo(
100
								AbstractDNetXsltFunctions.getDataInfo(null, "", "0.8", false, true).setInferenceprovenance(
101
										dedupConf.getWf().getConfigurationId())).setRel(oafRel)
102
				.build();
103
		return oaf.toByteArray();
104
	}
105

    
106
	private void emitDedupRel(final Context context, final byte[] cf, final byte[] from, final byte[] to, final byte[] value) throws IOException,
107
			InterruptedException {
108
		final Put put = new Put(from).add(cf, to, value);
109
		put.setWriteToWAL(JobParams.WRITE_TO_WAL);
110
		context.write(new ImmutableBytesWritable(from), put);
111
	}
112

    
113
}
(5-5/16)