View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.agent.module.sensor.visibility.model;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.FileOutputStream;
6   import java.io.IOException;
7   import java.io.ObjectInputStream;
8   import java.io.ObjectOutputStream;
9   import java.io.Serializable;
10  import java.util.BitSet;
11  import java.util.Collection;
12  import java.util.Iterator;
13  
14  /**
15   * Simple class to store bit-matrix for visibility between {@link VisibilityLocation}s.
16   * 
17   * THREAD-UNSAFE
18   * 
19   * @author Jimmy
20   */
21  public class BitMatrix implements Serializable {
22      
23      /**
24  	 * Randomly generated. 
25  	 */
26  	private static final long serialVersionUID = -6276264641650851997L;
27  
28  	/**
29       * Contains bit matrix.
30       * 
31       * matrix[colIndex] returns matrix's col (indexing by 'x') first.
32       */
33      private BitSet[] matrix;
34          
35      /**
36       * Number of rows in matrix (col is determined by matrix.length).
37       */
38      private int rows;    
39      
40      public BitMatrix(int columns, int rows) {
41          this.rows = rows;
42          this.matrix = new BitSet[columns];
43          for (int i = 0; i < columns; i++) {
44              this.matrix[i] = new BitSet(this.rows);
45          }
46      }
47      
48      /**
49       * Sets matrix[column, row] to TRUE
50       * @param column
51       * @param row
52       */
53      public void set(int column, int row) {
54      	matrix[column].set(row);
55      }
56      
57      /**
58       * Sets matrix[column, row] to 'state'
59       * @param column
60       * @param row
61       * @param state to set
62       */
63      public void set(int column, int row, boolean state) {
64      	if (state) {
65      		set(column, row);
66      	} else {
67      		unset(column, row);
68      	}
69      }
70      
71      /**
72       * Flips value in matrix[column, row]
73       * @param column
74       * @param row
75       */
76      public void flip(int column, int row) {
77      	matrix[column].flip(row);
78      }
79      
80      /**
81       * Sets matrix[column, row] to FALSE
82       * @param column
83       * @param row
84       */
85      public void unset(int column, int row) {
86      	matrix[column].clear(row);
87      }
88      
89      /**
90       * Returns 'column' of the matrix.
91       * @param column
92       * @return
93       */
94      public BitSet getColumn(int column) {
95      	return matrix[column];
96      }
97      
98      /**
99       * Returns matrix[column, row]
100      */
101     public boolean get(int column, int row) {
102         return this.matrix[column].get(row);
103     }
104     
105     /**
106      * Return logical-and of 'columns'.
107      * @param columns
108      * @return
109      */
110     public BitSet and(int... columns) {
111     	if (columns == null) return null;
112     	if (columns.length == 1) return getColumn(columns[0]);
113     	BitSet set = (BitSet) getColumn(columns[0]).clone();
114     	for (int i = 1; i < columns.length; ++i) {
115     		set.and(getColumn(columns[i]));
116     	}
117     	return set;
118     }
119     
120     /**
121      * Return logical-and of 'columns'.
122      * @param columns
123      * @return
124      */
125     public BitSet and(Collection<Integer> columns) {
126     	if (columns == null) return null;
127     	Iterator<Integer> keyIter = columns.iterator();
128     	BitSet set = (BitSet) getColumn(keyIter.next()).clone();
129     	while (keyIter.hasNext()) {
130     		set.and(getColumn(keyIter.next()));
131     	}
132     	return set;
133     }
134     
135     /**
136      * Return logical-or of 'columns'.
137      * @param columns
138      * @return
139      */
140     public BitSet or(int... columns) {
141     	if (columns == null) return null;
142     	if (columns.length == 1) return getColumn(columns[0]);
143     	BitSet set = (BitSet) getColumn(columns[0]).clone();
144     	for (int i = 1; i < columns.length; ++i) {
145     		set.or(getColumn(columns[i]));
146     	}
147     	return set;
148     }
149     
150     /**
151      * Return logical-and of 'columns'.
152      * @param columns
153      * @return
154      */
155     public BitSet or(Collection<Integer> columns) {
156     	if (columns == null) return null;
157     	Iterator<Integer> keyIter = columns.iterator();
158     	BitSet set = (BitSet) getColumn(keyIter.next()).clone();
159     	while (keyIter.hasNext()) {
160     		set.or(getColumn(keyIter.next()));
161     	}
162     	return set;
163     }
164     
165     public int columns() {
166         return matrix.length;
167     }
168     
169     public int rows() {
170     	return rows;
171     }
172     
173     @Override
174     public String toString() {
175     	return "BitMatrix[" + columns() + "x" + rows + "]";
176     }
177     
178     public void saveToFile(File file) {
179     	try {    		
180     		ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(file));
181     		try {
182     			output.writeObject(this);
183     		} finally {
184     			output.close();
185     		}    		
186     	} catch (IOException e) {
187     		throw new RuntimeException("Failed to save bitmatrix.", e);
188     	}
189     }
190     
191     public static BitMatrix loadFromFile(File file) {
192     	try {
193     		
194     		ObjectInputStream input = new ObjectInputStream(new FileInputStream(file));
195     		BitMatrix matrix;
196     		try {
197     			matrix = (BitMatrix)input.readObject();
198     		} finally {
199     			input.close();
200     		}
201     		return matrix;
202     		
203     	} catch (IOException e) {
204     		throw new RuntimeException("Failed to save bitmatrix.", e);
205     	} catch (ClassNotFoundException e) {
206 			throw new RuntimeException("Failed to load bitmatrix.", e);
207 		}
208     }
209     
210     /**
211      * Flips whole bitset passed.
212      * @param bitSet
213      */
214     public static void flip(BitSet bitSet) {
215     	bitSet.flip(0, bitSet.length());
216     }
217     
218 }