Subversion Repositories SmartDukaan

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 ashish 1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements. See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership. The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License. You may obtain a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied. See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
 
20
package org.apache.thrift;
21
 
22
import java.util.ArrayList;
23
import java.util.Arrays;
24
import java.util.Collection;
25
import java.util.HashSet;
26
import java.util.Iterator;
27
import java.util.List;
28
import java.util.Set;
29
 
30
/**
31
 * IntRangeSet is a specialized Set<Integer> implementation designed 
32
 * specifically to make the generated validate() method calls faster. It groups
33
 * the set values into ranges, and in the contains() call, it does 
34
 * num ranges * 2 comparisons max. For the common case, which is a single, 
35
 * contiguous range, this approach is about 60% faster than using a HashSet. If
36
 * you had a very ragged value set, like all the odd numbers, for instance, 
37
 * then you would end up with pretty poor running time.  
38
 */
39
public class IntRangeSet implements Set<Integer> {
40
  /**
41
   * This array keeps the bounds of each extent in alternating cells, always 
42
   * increasing. Example: [0,5,10,15], which corresponds to 0-5, 10-15.
43
   */
44
  private int[] extents;
45
 
46
  /**
47
   * We'll keep a duplicate, real HashSet around internally to satisfy some of
48
   * the other set operations. 
49
   */
50
  private Set<Integer> realSet = new HashSet<Integer>();
51
 
52
  public IntRangeSet(int... values) {
53
    Arrays.sort(values);
54
 
55
    List<Integer> extent_list = new ArrayList<Integer>();
56
 
57
    int ext_start = values[0];
58
    int ext_end_so_far = values[0];
59
    for (int i = 1; i < values.length; i++) {
60
      realSet.add(values[i]);
61
 
62
      if (values[i] == ext_end_so_far + 1) {
63
        // advance the end so far
64
        ext_end_so_far = values[i];
65
      } else {
66
        // create an extent for everything we saw so far, move on to the next one
67
        extent_list.add(ext_start);
68
        extent_list.add(ext_end_so_far);
69
        ext_start = values[i];
70
        ext_end_so_far = values[i];
71
      }
72
    }
73
    extent_list.add(ext_start);
74
    extent_list.add(ext_end_so_far);
75
 
76
    extents = new int[extent_list.size()];
77
    for (int i = 0; i < extent_list.size(); i++) {
78
      extents[i] = extent_list.get(i);
79
    }
80
  }
81
 
82
  public boolean add(Integer i) {
83
    throw new UnsupportedOperationException();
84
  }
85
 
86
  public void clear() {
87
    throw new UnsupportedOperationException();
88
  }
89
 
90
  public boolean addAll(Collection<? extends Integer> arg0) {
91
    throw new UnsupportedOperationException();
92
  }
93
 
94
  /**
95
   * While this method is here for Set interface compatibility, you should avoid 
96
   * using it. It incurs boxing overhead! Use the int method directly, instead.
97
   */
98
  public boolean contains(Object arg0) {
99
    return contains(((Integer)arg0).intValue());
100
  }
101
 
102
  /**
103
   * This is much faster, since it doesn't stop at Integer on the way through.
104
   * @param val the value you want to check set membership for
105
   * @return true if val was found, false otherwise
106
   */
107
  public boolean contains(int val) {
108
    for (int i = 0; i < extents.length / 2; i++) {
109
      if (val < extents[i*2]) {
110
        return false;
111
      } else if (val <= extents[i*2+1]) {
112
        return true;
113
      }
114
    }
115
 
116
    return false;
117
  }
118
 
119
  public boolean containsAll(Collection<?> arg0) {
120
    for (Object o : arg0) {
121
      if (!contains(o)) {
122
        return false;
123
      }
124
    }
125
    return true;
126
  }
127
 
128
  public boolean isEmpty() {
129
    return realSet.isEmpty();
130
  }
131
 
132
  public Iterator<Integer> iterator() {
133
    return realSet.iterator();
134
  }
135
 
136
  public boolean remove(Object arg0) {
137
    throw new UnsupportedOperationException();
138
  }
139
 
140
  public boolean removeAll(Collection<?> arg0) {
141
    throw new UnsupportedOperationException();
142
  }
143
 
144
  public boolean retainAll(Collection<?> arg0) {
145
    throw new UnsupportedOperationException();
146
  }
147
 
148
  public int size() {
149
    return realSet.size();
150
  }
151
 
152
  public Object[] toArray() {
153
    return realSet.toArray();
154
  }
155
 
156
  public <T> T[] toArray(T[] arg0) {
157
    return realSet.toArray(arg0);
158
  }
159
 
160
  @Override
161
  public String toString() {
162
    String buf = "";
163
    for (int i = 0; i < extents.length / 2; i++) {
164
      if (i != 0) { 
165
        buf += ", ";
166
      }
167
      buf += "[" + extents[i*2] + "," + extents[i*2+1] + "]"; 
168
    }
169
    return buf;
170
  }
171
}