All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.uam.eps.ir.relison.diffusion.io.backup.BinarySimulationWriter Maven / Gradle / Ivy

The newest version!
/*
 *  Copyright (C) 2020 Information Retrieval Group at Universidad Autónoma
 *  de Madrid, http://ir.ii.uam.es
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package es.uam.eps.ir.relison.diffusion.io.backup;

import es.uam.eps.ir.relison.diffusion.data.Data;
import es.uam.eps.ir.relison.diffusion.simulation.Iteration;
import es.uam.eps.ir.relison.diffusion.simulation.Simulation;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Writes a simulation into a file. Data is stored in binary fields,
 * storing the identifiers of each object.
 *
 * @author Javier Sanz-Cruzado ([email protected])
 * @author Pablo Castells ([email protected])
 *
 * @param  Type of the users.
 * @param  Type of the information pieces.
 * @param 

Type of the parameters. */ public class BinarySimulationWriter implements SimulationWriter { /** * Object output stream for writing into file. */ private DataOutputStream oos; /** * Constructor. */ public BinarySimulationWriter() { oos = null; } @Override public boolean initialize(String file) { if(file == null || oos != null) return false; try { File f = new File(file); if(f.exists()) { f.delete(); } this.oos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); return true; } catch (IOException ex) { return false; } } @Override public boolean writeSimulation(Simulation simulation) { if(simulation == null || this.oos == null) return false; try { int initial = simulation.getInitialNumber(); oos.writeInt(initial); int numIter = simulation.getNumIterations(); // Write the number of iterations oos.writeInt(numIter); boolean outcome = true; // Write each iteration for(int i = initial; i < (numIter + initial); ++i) { outcome = outcome && this.writeIteration(simulation, i); } return outcome; } catch(IOException exception) { return false; } } @Override public boolean writeIteration(Simulation simulation, int numIter) { if(this.oos == null || simulation == null || numIter < simulation.getInitialNumber() || numIter > (simulation.getNumIterations()+simulation.getInitialNumber())) { return false; } try { Data data = simulation.getData(); Iteration iteration = simulation.getIteration(numIter); if(iteration == null) { return false; } // Write the iteration number oos.writeInt(iteration.getIterationNumber()); /* **************** Users that receive new information pieces ********************/ // Write the number of users that receive at least one new information piece. int numUsers = iteration.getNumReceivingUsers(); oos.writeInt(numUsers); // Write the information about the newly received pieces of information. if(numUsers > 0) { List users = iteration.getReceivingUsers().collect(Collectors.toCollection(ArrayList::new)); // For each user which has received at least a new piece... for(U u : users) { // Get the pieces received by the user Map> infoPieces = new HashMap<>(); iteration.getSeenInformation(u).forEach(p -> infoPieces.put(p.v1(), p.v2())); if(!this.writeReceivedDataUser(data, u, infoPieces)) { return false; } } } /* **************** Users that receive previously received information pieces ********************/ // Write the number of users that receive at least one previously received information piece. numUsers = iteration.getNumReReceivingUsers(); oos.writeInt(numUsers); // Write the information about the previously received pieces of information. if(numUsers > 0) { List users = iteration.getReReceivingUsers().collect(Collectors.toCollection(ArrayList::new)); // For each user which has received at least a previously received piece... for(U u : users) { // Get the pieces received by the user Map> infoPieces = new HashMap<>(); iteration.getReReceivedInformation(u).forEach(p -> infoPieces.put(p.v1(), p.v2())); if(!this.writeReceivedDataUser(data, u, infoPieces)) { return false; } } } /* **************** Users that propagate information pieces ********************/ // Write the number of users that propagate at least one new information piece. numUsers = iteration.getNumPropagatingUsers(); oos.writeInt(numUsers); // Write the information about the propagated pieces of information. if(numUsers > 0) { List users = iteration.getPropagatingUsers().collect(Collectors.toCollection(ArrayList::new)); // For each user which has propagated at least a new piece... for(U u : users) { // Get the pieces propagated by the user List infoPieces = iteration.getPropagatedInformation(u).collect(Collectors.toCollection(ArrayList::new)); if(!this.writeUserActions(data, u, infoPieces)) { return false; } } } /* **************** Users that discard information pieces ********************/ // Write the number of users that discarded at least one information piece. numUsers = iteration.getNumDiscardingUsers(); oos.writeInt(numUsers); // Write the information about the discarded pieces of information. if(numUsers > 0) { List users = iteration.getDiscardingUsers().collect(Collectors.toCollection(ArrayList::new)); // For each user which has discarded at least a piece... for(U u : users) { // Get the pieces discarded by the user List infoPieces = iteration.getDiscardedInformation(u).collect(Collectors.toCollection(ArrayList::new)); if(!this.writeUserActions(data, u, infoPieces)) { return false; } } } return true; } catch (IOException ex) { return false; } } /** * Given a single user, and the data he has received, writes it to a binary file * @param data the full data. * @param u the user to write. * @param infoPieces the set of received information pieces. * @return true if everything went OK, false if not. */ private boolean writeReceivedDataUser(Data data, U u, Map> infoPieces) { try { int uidx = data.getUserIndex().object2idx(u); // Write the id. of the user oos.writeInt(uidx); // Write the number of received pieces. oos.writeInt(infoPieces.size()); // Write the information for each piece for(I i : infoPieces.keySet()) { // Write the identifier of each piece. int iidx = data.getInformationPiecesIndex().object2idx(i); oos.writeInt(iidx); // Write the creators Set creators = infoPieces.get(i); // Write the number of creators oos.writeInt(creators.size()); for(U v : creators) { int vidx = data.getUserIndex().object2idx(v); // Write the identifier of each creator. oos.writeInt(vidx); } } return true; } catch(IOException ex) { return false; } } /** * Given a single user, writes about the information pieces the user has interacted with * (propagated or discarded) into a binary file. * @param data the full data. * @param u the user. * @param infoPieces the list of interaction pieces the user has interacted with. * @return true if everything went OK, false otherwise. */ private boolean writeUserActions(Data data, U u, List infoPieces) { try { int uidx = data.getUserIndex().object2idx(u); oos.writeInt(uidx); // Write the number of propagated pieces. oos.writeInt(infoPieces.size()); // For each piece, write its identifier. for(I i : infoPieces) { int iidx = data.getInformationPiecesIndex().object2idx(i); oos.writeInt(iidx); } return true; } catch(IOException ex) { return false; } } @Override public boolean close() { if(oos != null) { try { oos.close(); oos = null; return true; } catch (IOException ex) { return false; } } return false; } }