File: ArrayMap.drv

package info (click to toggle)
libfastutil-java 6.5.15-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,716 kB
  • ctags: 1,035
  • sloc: java: 9,711; sh: 588; makefile: 423; xml: 211
file content (326 lines) | stat: -rw-r--r-- 9,994 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/*		 
 * Copyright (C) 2007-2014 Sebastiano Vigna 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */


package PACKAGE;

import java.util.Map;
import java.util.NoSuchElementException;
import it.unimi.dsi.fastutil.objects.AbstractObjectIterator;
import it.unimi.dsi.fastutil.objects.AbstractObjectSet;
import it.unimi.dsi.fastutil.objects.ObjectIterator;

import VALUE_PACKAGE.VALUE_COLLECTION;
import VALUE_PACKAGE.VALUE_COLLECTIONS;
import VALUE_PACKAGE.VALUE_ARRAY_SET;
import VALUE_PACKAGE.VALUE_ARRAYS;

/** A simple, brute-force implementation of a map based on two parallel backing arrays. 
 * 
 * <p>The main purpose of this
 * implementation is that of wrapping cleanly the brute-force approach to the storage of a very 
 * small number of pairs: just put them into two parallel arrays and scan linearly to find an item.
 */

public class ARRAY_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP KEY_VALUE_GENERIC implements java.io.Serializable, Cloneable {

	private static final long serialVersionUID = 1L;
	/** The keys (valid up to {@link #size}, excluded). */
	private transient KEY_TYPE[] key;
	/** The values (parallel to {@link #key}). */
	private transient VALUE_TYPE[] value;
	/** The number of valid entries in {@link #key} and {@link #value}. */
	private int size;
	
	/** Creates a new empty array map with given key and value backing arrays. The resulting map will have as many entries as the given arrays.
	 * 
	 * <p>It is responsibility of the caller that the elements of <code>key</code> are distinct.
	 * 
	 * @param key the key array.
	 * @param value the value array (it <em>must</em> have the same length as <code>key</code>).
	 */
	public ARRAY_MAP( final KEY_TYPE[] key, final VALUE_TYPE[] value ) {
		this.key = key;
		this.value = value;
		size = key.length;
		if( key.length != value.length ) throw new IllegalArgumentException( "Keys and values have different lengths (" + key.length + ", " + value.length + ")" );
	}

	/** Creates a new empty array map.
	 */
	public ARRAY_MAP() {
		this.key = ARRAYS.EMPTY_ARRAY;
		this.value = VALUE_ARRAYS.EMPTY_ARRAY;
	}
	
	/** Creates a new empty array map of given capacity.
	 *
	 * @param capacity the initial capacity.
	 */ 
	public ARRAY_MAP( final int capacity ) {
		this.key = new KEY_TYPE[ capacity ];
		this.value = new VALUE_TYPE[ capacity ];
	}
	
	/** Creates a new empty array map copying the entries of a given map.
	 *
	 * @param m a map.
	 */ 
	public ARRAY_MAP( final MAP KEY_VALUE_GENERIC m ) {
		this( m.size() );
		putAll( m );
	}
	
	/** Creates a new empty array map copying the entries of a given map.
	 *
	 * @param m a map.
	 */ 
	public ARRAY_MAP( final Map<? extends KEY_GENERIC_CLASS, ? extends VALUE_GENERIC_CLASS> m ) {
		this( m.size() );
		putAll( m );
	}
	
	/** Creates a new array map with given key and value backing arrays, using the given number of elements.
	 * 
	 * <p>It is responsibility of the caller that the first <code>size</code> elements of <code>key</code> are distinct.
	 * 
	 * @param key the key array.
	 * @param value the value array (it <em>must</em> have the same length as <code>key</code>).
	 * @param size the number of valid elements in <code>key</code> and <code>value</code>.
	 */
	public ARRAY_MAP( final KEY_TYPE[] key, final VALUE_TYPE[] value, final int size ) {
		this.key = key;
		this.value = value;
		this.size = size;
		if( key.length != value.length ) throw new IllegalArgumentException( "Keys and values have different lengths (" + key.length + ", " + value.length + ")" );
		if ( size > key.length ) throw new IllegalArgumentException( "The provided size (" + size + ") is larger than or equal to the backing-arrays size (" + key.length + ")" );
	}

	private final class EntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC> implements FastEntrySet KEY_VALUE_GENERIC {

		@Override
		public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() {
			return new AbstractObjectIterator<MAP.Entry KEY_VALUE_GENERIC>() {
				int next = 0;
				
				public boolean hasNext() {
					return next < size;
				}

				@SuppressWarnings("unchecked")
				public Entry KEY_VALUE_GENERIC next() {
					if ( ! hasNext() ) throw new NoSuchElementException();
					return new ABSTRACT_MAP.BasicEntry KEY_VALUE_GENERIC( KEY_GENERIC_CAST key[ next ], VALUE_GENERIC_CAST value[ next++ ] );
				}
				
			};
		}

		public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC> fastIterator() {
			return new AbstractObjectIterator<MAP.Entry KEY_VALUE_GENERIC>() {
				int next = 0;
				final BasicEntry KEY_VALUE_GENERIC entry = new BasicEntry KEY_VALUE_GENERIC ( KEY_NULL, VALUE_NULL );
				
				public boolean hasNext() {
					return next < size;
				}

				@SuppressWarnings("unchecked")
				public Entry KEY_VALUE_GENERIC next() {
					if ( ! hasNext() ) throw new NoSuchElementException();
					entry.key = KEY_GENERIC_CAST key[ next ];
					entry.value = VALUE_GENERIC_CAST value[ next++ ];
					return entry;
				}
				
			};
		}

		public int size() {
			return size;
		}

		@SuppressWarnings("unchecked")
		public boolean contains( Object o ) {
			if ( ! ( o instanceof Map.Entry ) ) return false;
			final Map.Entry<KEY_GENERIC_CLASS, VALUE_GENERIC_CLASS> e = (Map.Entry<KEY_GENERIC_CLASS, VALUE_GENERIC_CLASS>)o;
			final KEY_GENERIC_TYPE k = KEY_CLASS2TYPE( e.getKey() );
			return ARRAY_MAP.this.containsKey( k ) && VALUE_EQUALS( ARRAY_MAP.this.GET_VALUE( k ), VALUE_CLASS2TYPE( e.getValue() ) );
		}
		
	}

	public FastEntrySet KEY_VALUE_GENERIC ENTRYSET() {
		return new EntrySet();
	}

	private int findKey( final KEY_TYPE k ) {
		final KEY_TYPE[] key = this.key;
		for( int i = size; i-- != 0; ) if ( KEY_EQUALS( key[ i ], k ) ) return i;
		return -1;
	}

	@SuppressWarnings("unchecked")
#if #keys(primitive) || #values(primitive)
	public VALUE_GENERIC_TYPE GET_VALUE( final KEY_TYPE k ) {
#else
	public VALUE_GENERIC_TYPE get( final Object k ) {
#endif
		final KEY_TYPE[] key = this.key;
		for( int i = size; i-- != 0; ) if ( KEY_EQUALS( key[ i ], k ) ) return VALUE_GENERIC_CAST value[ i ];
		return defRetValue;
	}

	public int size() {
		return size;
	}

	@Override
	public void clear() {
#if #keys(reference) || #values(reference)
		for( int i = size; i-- != 0; ) {
#if #keys(reference)
			key[ i ] = null;
#endif
#if #values(reference)
			value[ i ] = null;
#endif
		}
#endif
		size = 0;
	}

	@Override
	public boolean containsKey( final KEY_TYPE k ) {
		return findKey( k ) != -1;
	}

	@Override
	@SuppressWarnings("unchecked")
	public boolean containsValue( VALUE_TYPE v ) {
		for( int i = size; i-- != 0; ) if ( VALUE_EQUALS( value[ i ], v ) ) return true;
		return false;
	}

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	@SuppressWarnings("unchecked")
	public VALUE_GENERIC_TYPE put( KEY_GENERIC_TYPE k, VALUE_GENERIC_TYPE v ) {
		final int oldKey = findKey( k );
		if ( oldKey != -1 ) {
			final VALUE_GENERIC_TYPE oldValue = VALUE_GENERIC_CAST value[ oldKey ];
			value[ oldKey ] = v;
			return oldValue;
		}
		if ( size == key.length ) {
			final KEY_TYPE[] newKey = new KEY_TYPE[ size == 0 ? 2 : size * 2 ];
			final VALUE_TYPE[] newValue = new VALUE_TYPE[ size == 0 ? 2 : size * 2 ];
			for( int i = size; i-- != 0; ) {
				newKey[ i ] = key[ i ];
				newValue[ i ] = value[ i ];
			}
			key = newKey;
			value = newValue;
		}
		key[ size ] = k;
		value[ size ] = v;
		size++;
		return defRetValue;
	}

	@Override
	@SuppressWarnings("unchecked")

#if #keys(primitive) || #values(primitive)
	public VALUE_GENERIC_TYPE REMOVE_VALUE( final KEY_TYPE k ) {
#else
	public VALUE_GENERIC_TYPE remove( final Object k ) {
#endif
		final int oldPos = findKey( k );
		if ( oldPos == -1 ) return defRetValue;
		final VALUE_GENERIC_TYPE oldValue = VALUE_GENERIC_CAST value[ oldPos ];
		final int tail = size - oldPos - 1;
		for( int i = 0; i < tail; i++ ) {
			key[ oldPos + i ] = key[ oldPos + i + 1 ];
			value[ oldPos + i ] = value[ oldPos + i + 1 ];
		}
		size--;
#if #keys(reference)
		key[ size ] = null;
#endif
#if #values(reference)
		value[ size ] = null;
#endif
		return oldValue;
	}

	@Override

	@SuppressWarnings("unchecked")
	public SET KEY_GENERIC keySet() {
		return new ARRAY_SET KEY_GENERIC( key, size );
	}

	@Override
	public VALUE_COLLECTION VALUE_GENERIC values() {
		return VALUE_COLLECTIONS.unmodifiable( new VALUE_ARRAY_SET VALUE_GENERIC( value, size ) );
	}

	/** Returns a deep copy of this map. 
	 *
	 * <P>This method performs a deep copy of this hash map; the data stored in the
	 * map, however, is not cloned. Note that this makes a difference only for object keys.
	 *
	 *  @return a deep copy of this map.
	 */

	@SuppressWarnings("unchecked")
	public ARRAY_MAP KEY_VALUE_GENERIC clone() {
		ARRAY_MAP KEY_VALUE_GENERIC c;
		try {
			c = (ARRAY_MAP KEY_VALUE_GENERIC)super.clone();
		}
		catch(CloneNotSupportedException cantHappen) {
			throw new InternalError();
		}
		c.key = key.clone();
		c.value = value.clone();
		return c;
	}
	
	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
		s.defaultWriteObject();
		for( int i = 0; i < size; i++ ) {
			s.WRITE_KEY( key[ i ] );
			s.WRITE_VALUE( value[ i ] );
		}
	}

	@SuppressWarnings("unchecked")
	private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
		s.defaultReadObject();
		key = new KEY_TYPE[ size ];
		value = new VALUE_TYPE[ size ];
		for( int i = 0; i < size; i++ ) {
			key[ i ] = s.READ_KEY();
			value[ i ] = s.READ_VALUE();
		}
	}
}