1 package org.apache.lucene.facet.taxonomy.writercache.cl2o;
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;
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
20 * http://www.apache.org/licenses/LICENSE-2.0
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.
30 * Similar to {@link StringBuilder}, but with a more efficient growing strategy.
31 * This class uses char array blocks to grow.
33 * @lucene.experimental
35 class CharBlockArray implements Appendable, Serializable, CharSequence {
37 private static final long serialVersionUID = 1L;
39 private final static int DefaultBlockSize = 32 * 1024; // 32 KB default size
41 final static class Block implements Serializable, Cloneable {
42 private static final long serialVersionUID = 1L;
48 this.chars = new char[size];
59 this(DefaultBlockSize);
62 CharBlockArray(int blockSize) {
63 this.blocks = new ArrayList<Block>();
64 this.blockSize = blockSize;
68 private void addBlock() {
69 this.current = new Block(this.blockSize);
70 this.blocks.add(this.current);
73 int blockIndex(int index) {
74 return index / blockSize;
77 int indexInBlock(int index) {
78 return index % blockSize;
81 public CharBlockArray append(CharSequence chars) {
82 return append(chars, 0, chars.length());
85 public CharBlockArray append(char c) {
86 if (this.current.length == this.blockSize) {
89 this.current.chars[this.current.length++] = c;
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));
103 public CharBlockArray append(char[] chars, int start, int length) {
107 if (this.current.length == this.blockSize) {
111 int remainingInBlock = this.blockSize - this.current.length;
112 if (remainingInBlock < toCopy) {
113 toCopy = remainingInBlock;
115 System.arraycopy(chars, offset, this.current.chars, this.current.length, toCopy);
118 this.current.length += toCopy;
121 this.length += length;
125 public CharBlockArray append(String s) {
126 int remain = s.length();
129 if (this.current.length == this.blockSize) {
133 int remainingInBlock = this.blockSize - this.current.length;
134 if (remainingInBlock < toCopy) {
135 toCopy = remainingInBlock;
137 s.getChars(offset, offset + toCopy, this.current.chars, this.current.length);
140 this.current.length += toCopy;
143 this.length += s.length();
147 public char charAt(int index) {
148 Block b = this.blocks.get(blockIndex(index));
149 return b.chars[indexInBlock(index)];
152 public int length() {
156 public CharSequence subSequence(int start, int end) {
157 throw new UnsupportedOperationException("subsequence not implemented yet");
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);
169 void flush(OutputStream out) throws IOException {
170 ObjectOutputStream oos = null;
172 oos = new ObjectOutputStream(out);
173 oos.writeObject(this);
182 public static CharBlockArray open(InputStream in) throws IOException, ClassNotFoundException {
183 ObjectInputStream ois = null;
185 ois = new ObjectInputStream(in);
186 CharBlockArray a = (CharBlockArray) ois.readObject();