add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / facet / src / java / org / apache / lucene / facet / taxonomy / writercache / cl2o / CharBlockArray.java
1 package org.apache.lucene.facet.taxonomy.writercache.cl2o;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.ObjectInputStream;
6 import java.io.ObjectOutputStream;
7 import java.io.OutputStream;
8 import java.io.Serializable;
9 import java.util.ArrayList;
10 import java.util.List;
11
12 /**
13  * Licensed to the Apache Software Foundation (ASF) under one or more
14  * contributor license agreements.  See the NOTICE file distributed with
15  * this work for additional information regarding copyright ownership.
16  * The ASF licenses this file to You under the Apache License, Version 2.0
17  * (the "License"); you may not use this file except in compliance with
18  * the License.  You may obtain a copy of the License at
19  *
20  *     http://www.apache.org/licenses/LICENSE-2.0
21  *
22  * Unless required by applicable law or agreed to in writing, software
23  * distributed under the License is distributed on an "AS IS" BASIS,
24  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  * See the License for the specific language governing permissions and
26  * limitations under the License.
27  */
28
29 /**
30  * Similar to {@link StringBuilder}, but with a more efficient growing strategy.
31  * This class uses char array blocks to grow.
32  * 
33  * @lucene.experimental
34  */
35 class CharBlockArray implements Appendable, Serializable, CharSequence {
36
37   private static final long serialVersionUID = 1L;
38
39   private final static int DefaultBlockSize = 32 * 1024;  // 32 KB default size
40
41   final static class Block implements Serializable, Cloneable {
42     private static final long serialVersionUID = 1L;
43
44     char[] chars;
45     int length;
46
47     Block(int size) {
48       this.chars = new char[size];
49       this.length = 0;
50     }
51   }
52
53   List<Block> blocks;
54   Block current;
55   int blockSize;
56   int length;
57
58   CharBlockArray() {
59     this(DefaultBlockSize);
60   }
61
62   CharBlockArray(int blockSize) {
63     this.blocks = new ArrayList<Block>();
64     this.blockSize = blockSize;
65     addBlock();
66   }
67
68   private void addBlock() {
69     this.current = new Block(this.blockSize);
70     this.blocks.add(this.current);
71   }
72
73   int blockIndex(int index) {
74     return index / blockSize;
75   }
76
77   int indexInBlock(int index) {
78     return index % blockSize;
79   }
80
81   public CharBlockArray append(CharSequence chars) {
82     return append(chars, 0, chars.length());
83   }
84
85   public CharBlockArray append(char c) {
86     if (this.current.length == this.blockSize) {
87       addBlock();
88     }
89     this.current.chars[this.current.length++] = c;
90     this.length++;
91
92     return this;
93   }
94
95   public CharBlockArray append(CharSequence chars, int start, int length) {
96     int end = start + length;
97     for (int i = start; i < end; i++) {
98       append(chars.charAt(i));
99     }
100     return this;
101   }
102
103   public CharBlockArray append(char[] chars, int start, int length) {
104     int offset = start;
105     int remain = length;
106     while (remain > 0) {
107       if (this.current.length == this.blockSize) {
108         addBlock();
109       }
110       int toCopy = remain;
111       int remainingInBlock = this.blockSize - this.current.length;
112       if (remainingInBlock < toCopy) {
113         toCopy = remainingInBlock;
114       }
115       System.arraycopy(chars, offset, this.current.chars, this.current.length, toCopy);
116       offset += toCopy;
117       remain -= toCopy;
118       this.current.length += toCopy;
119     }
120
121     this.length += length;
122     return this;
123   }
124
125   public CharBlockArray append(String s) {
126     int remain = s.length();
127     int offset = 0;
128     while (remain > 0) {
129       if (this.current.length == this.blockSize) {
130         addBlock();
131       }
132       int toCopy = remain;
133       int remainingInBlock = this.blockSize - this.current.length;
134       if (remainingInBlock < toCopy) {
135         toCopy = remainingInBlock;
136       }
137       s.getChars(offset, offset + toCopy, this.current.chars, this.current.length);
138       offset += toCopy;
139       remain -= toCopy;
140       this.current.length += toCopy;
141     }
142
143     this.length += s.length();
144     return this;
145   }
146
147   public char charAt(int index) {
148     Block b = this.blocks.get(blockIndex(index));
149     return b.chars[indexInBlock(index)];
150   }
151
152   public int length() {
153     return this.length;
154   }
155
156   public CharSequence subSequence(int start, int end) {
157     throw new UnsupportedOperationException("subsequence not implemented yet");
158   }
159
160   @Override
161   public String toString() {
162     StringBuilder b = new StringBuilder(blockSize * this.blocks.size());
163     for (int i = 0; i < this.blocks.size(); i++) {
164       b.append(this.blocks.get(i).chars);
165     }
166     return b.toString();
167   }
168
169   void flush(OutputStream out) throws IOException {
170     ObjectOutputStream oos = null;
171     try {
172       oos = new ObjectOutputStream(out);
173       oos.writeObject(this);
174       oos.flush();
175     } finally {
176       if (oos != null) {
177         oos.close();
178       }
179     }
180   }
181
182   public static CharBlockArray open(InputStream in) throws IOException, ClassNotFoundException {
183     ObjectInputStream ois = null;
184     try {
185       ois = new ObjectInputStream(in);
186       CharBlockArray a = (CharBlockArray) ois.readObject();
187       return a;
188     } finally {
189       if (ois != null) {
190         ois.close();
191       }
192     }
193   }
194
195 }