Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Implementazione della Map

Una volta implementata una funzione di Map, analizziamo il ruolo del framework nel gestire i file di input e di output nelle operazioni di lettura e scrittura dei file di I/O, limitando al minimo la necessità di un intervento da parte dello sviluppatore.
Una volta implementata una funzione di Map, analizziamo il ruolo del framework nel gestire i file di input e di output nelle operazioni di lettura e scrittura dei file di I/O, limitando al minimo la necessità di un intervento da parte dello sviluppatore.
Link copiato negli appunti

Implementazione della Map

Per implementare la funzione MAP, creiamo una classe nel package map e la chiamiamo Map. Durante la creazione della classe, dobbiamo avere cura di ereditare la classe Mapper. Per fare ciò, possiamo parametrizzare la maschera di creazione di una classe come nella figura sottostante:

Figura 1. Creazione della classe Map
Creazione della classe Map

Come possiamo notare nel campo "Superclass" della maschera, Mapper può essere parametrizzata sostituendo gli input e gli output, noti dalla fase di progettazione. La classe ha la struttura seguente:

public class Map extends Mapper {
	public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {}
}

La classe estesa permette di mappare gli oggetti di input <KeyIN,ValueIN> della funzione Map rappresentati dai primi due parametri di Mapper (parametrizzati nel nostro caso con oggetti LongWritable e Text) con gli oggetti di output <KeyOUT,ValueOUT> (Text e IntWritable) che a loro volta costituiranno gli input della funzione Reduce. Possiamo quindi immaginare il motivo della presenza dei primi due parametri dello stesso tipo di <KeyIN,ValueIN> per il metodo map().

L'oggetto value contiene una riga letta dal file di input. Ottenuta la stringa contenuta in value, possiamo tokenizzarla, incapsularla in un oggetto locale di tipo Text che verrà dato in output incapsulandolo nell'oggetto context (ultimo parametro di ingresso di map). Traducendo in codice quanto detto otteniamo la seguente implementazione del metodo map:

public class Map extends Mapper {
	private final static IntWritable one = new IntWritable(1);
	private Text word = new Text();
	public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
		String line = value.toString();
		StringTokenizer tokenizer = new StringTokenizer(line);
		while (tokenizer.hasMoreTokens()) {
			word.set(tokenizer.nextToken());
			context.write(word, one);
		}
	}
}

Notiamo quindi l'utilizzo di due oggetti della classe Map (one e word) che vengono utilizzati come l'output intermedio e inoltrati al Reduce attraverso il metodo write() dell'oggetto context. Con un procedimento analogo creiamo la classe Reduce all'interno del relativo package:

Figura 2. Creazione della classe Reduce
Creazione della classe Reduce

Ancora una volta la classe Reducer può essere parametrizzata sostituendo opportunamente gli input e gli output. La classe creata ha la struttura seguente:

public class Reduce extends Reducer {
	public void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {}
}

I valori di interesse in input sono incapsulati nell'oggetto Iterable. Scorrendo questo elenco infatti, possiamo recuperare i singoli valori e ricostruire il numero di occorrenze sommandoli ad ogni iterazione:

public class Reduce extends Reducer {
	public void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {
		int sum = 0;
		for (IntWritable val : values) {
			sum += val.get();
		}
		context.write(key, new IntWritable(sum));
	}
}

Il risultato dell'elaborazione della funzione reduce, viene fornito attraverso il metodo write() dell'oggetto context. All'intero del codice non è stato necessario gestire i file di input e di output: delle operazioni di lettura/scrittura dei file di I/O infatti se ne occupa il framework. Lo sviluppatore si occuperà solo di specificare quelle che sono le directory di input e di output (classe Main).

Ti consigliamo anche