2 * Copyright (C) 2006 Robin Rosenberg <robin.rosenberg@dewire.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License, version 2, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org
.spearce
.jgit
.lib
;
19 import java
.lang
.reflect
.InvocationTargetException
;
20 import java
.lang
.reflect
.Method
;
21 import java
.util
.AbstractMap
;
22 import java
.util
.ArrayList
;
23 import java
.util
.Collection
;
24 import java
.util
.HashSet
;
25 import java
.util
.List
;
28 import java
.util
.TreeMap
;
31 * Very much like a map, but specialized to partition the data on the first byte
32 * of the key. This is about twice as fast. See test class.
34 * Inspiration is taken from the Git pack file format which uses this technique
35 * to improve lookup performance.
38 * The value we map ObjectId's to.
41 public class ObjectIdMap
<V
> extends AbstractMap
<ObjectId
, V
> {
43 @SuppressWarnings("unchecked")
44 private Map
<ObjectId
, V
>[] level0
= new Map
[256];
47 * Construct an ObjectIdMap with an underlying TreeMap implementation
49 public ObjectIdMap() {
54 * Construct an ObjectIdMap with the same underlying map implementation as
55 * the provided example.
59 @SuppressWarnings("unchecked")
60 public ObjectIdMap(Map sample
) {
62 Method m
=sample
.getClass().getMethod("clone", (Class
[])null);
63 for (int i
=0; i
<256; ++i
) {
64 level0
[i
] = (Map
)m
.invoke(sample
, (Object
[])null);
66 } catch (IllegalAccessException e
) {
67 throw new IllegalArgumentException(e
);
68 } catch (IllegalArgumentException e
) {
69 throw new IllegalArgumentException(e
);
70 } catch (InvocationTargetException e
) {
71 throw new IllegalArgumentException(e
);
72 } catch (SecurityException e
) {
73 throw new IllegalArgumentException(e
);
74 } catch (NoSuchMethodException e
) {
75 throw new IllegalArgumentException(e
);
80 for (int i
=0; i
<256; ++i
)
84 public boolean containsKey(Object key
) {
85 return submap((ObjectId
)key
).containsKey(key
);
88 private final Map
<ObjectId
, V
> submap(ObjectId key
) {
89 return level0
[key
.getFirstByte()];
92 public boolean containsValue(Object value
) {
93 for (int i
=0; i
<256; ++i
)
94 if (level0
[i
].containsValue(value
))
99 public Set
<Map
.Entry
<ObjectId
, V
>> entrySet() {
100 Set
<Map
.Entry
<ObjectId
, V
>> ret
= new HashSet
<Map
.Entry
<ObjectId
, V
>>();
101 for (int i
=0; i
<256; ++i
)
102 ret
.addAll(level0
[i
].entrySet());
106 public V
get(Object key
) {
107 return submap((ObjectId
)key
).get(key
);
110 public boolean isEmpty() {
111 for (int i
=0; i
<256; ++i
)
112 if (!level0
[i
].isEmpty())
117 public Set
<ObjectId
> keySet() {
118 Set
<ObjectId
> ret
= new HashSet
<ObjectId
>();
119 for (int i
=0; i
<256; ++i
)
120 ret
.addAll(level0
[i
].keySet());
124 @SuppressWarnings("unchecked")
125 public V
put(ObjectId key
, V value
) {
126 return submap(key
).put(key
, value
);
129 public void putAll(Map
<?
extends ObjectId
, ?
extends V
> arg0
) {
130 for (ObjectId k
: arg0
.keySet()) {
136 public V
remove(Object key
) {
137 return submap((ObjectId
) key
).remove(key
);
142 for (int i
=0; i
<256; ++i
)
143 ret
+= level0
[i
].size();
147 public Collection
<V
> values() {
148 List
<V
> ret
=new ArrayList
<V
>(size());
149 for (int i
=0; i
<256; ++i
)
150 ret
.addAll(level0
[i
].values());