001: /*
002: * RowDataList.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.storage;
013:
014: import java.util.Arrays;
015: import java.util.Comparator;
016:
017: /**
018: * A class to store a dynamic array of {@link RowData} objects
019: */
020: public class RowDataList {
021: private static final int DEFAULT_SIZE = 150;
022:
023: // growth factor when increasing the array
024: private float grow = 1.10f;
025: private int size;
026: private RowData data[];
027:
028: public RowDataList() {
029: this (DEFAULT_SIZE);
030: }
031:
032: public RowDataList(int len) {
033: this .data = new RowData[len];
034: this .size = 0;
035: }
036:
037: private void grow(int minStorage) {
038: if (this .data == null) {
039: data = new RowData[(int) (minStorage * grow)];
040: } else {
041: int newStorage = (int) (this .data.length * grow) + 1;
042: if (newStorage < minStorage)
043: newStorage = minStorage;
044:
045: synchronized (this .data) {
046: RowData newBuf[] = new RowData[newStorage];
047: System.arraycopy(this .data, 0, newBuf, 0, this .size);
048: this .data = newBuf;
049: }
050: }
051: }
052:
053: public void ensureCapacity(int newSize) {
054: this .grow(newSize);
055: }
056:
057: /**
058: * Free all objects stored in the internal array. This will
059: * also call reset on all RowData objects, so if rows are shared
060: * between to RowDataList instances (moved back and forth, e.g.
061: * when filtering) this will also remove the data from the original
062: * source.
063: * @see #clear()
064: * @see RowData#reset()
065: */
066: public void reset() {
067: synchronized (this .data) {
068: for (RowData row : data) {
069: if (row != null)
070: row.reset();
071: }
072: }
073: clear();
074: }
075:
076: /**
077: * set the number of rows to zero.
078: * The RowData instances currently stored in this list
079: * are not freed by calling RowData.reset()
080: * @see #reset()
081: */
082: public void clear() {
083: this .size = 0;
084: this .data = null;
085: }
086:
087: /**
088: * Return the number of rows in this list
089: */
090: public int size() {
091: return this .size;
092: }
093:
094: /**
095: * Return the row at the given index
096: */
097: public RowData get(int index) {
098: if (data == null)
099: throw new ArrayIndexOutOfBoundsException(index);
100: synchronized (this .data) {
101: return this .data[index];
102: }
103: }
104:
105: /**
106: * Remove the row at the specified index
107: */
108: public void remove(int index) {
109: if (data == null)
110: throw new ArrayIndexOutOfBoundsException(index);
111: int count = size - index - 1;
112:
113: synchronized (this .data) {
114: if (count > 0) {
115: System.arraycopy(data, index + 1, data, index, count);
116: }
117: this .size--;
118: this .data[size] = null;
119: }
120: }
121:
122: /**
123: * Add a row to this list.
124: * @return the new size of this list
125: */
126: public int add(RowData row) {
127: if (data == null) {
128: grow(DEFAULT_SIZE);
129: }
130:
131: int newlen = this .size + 1;
132:
133: synchronized (this .data) {
134: if (newlen > this .data.length)
135: grow(newlen);
136: this .data[newlen - 1] = row;
137: this .size = newlen;
138: return this .size;
139: }
140: }
141:
142: /**
143: * Add a row at a specific index in this list
144: */
145: public int add(int index, RowData row) {
146: int newlen = this .size + 1;
147: synchronized (this .data) {
148: if (data == null) {
149: grow(DEFAULT_SIZE);
150: } else if (newlen > this .data.length) {
151: // we are not using ensureCapacity here to optimize
152: // the calls to System.arraycopy
153: RowData newBuf[] = new RowData[(int) (newlen * grow)];
154: System.arraycopy(this .data, 0, newBuf, 0, index);
155: System.arraycopy(this .data, index, newBuf, index + 1,
156: (size - index));
157: this .data = newBuf;
158: } else {
159: System.arraycopy(this .data, index, this .data,
160: index + 1, (size - index));
161: }
162: this .data[index] = row;
163: this .size = newlen;
164: return index;
165: }
166: }
167:
168: public void sort(Comparator<RowData> comp) {
169: if (size == 0 || data == null)
170: return;
171: synchronized (this .data) {
172: Arrays.sort(this .data, 0, this.size, comp);
173: }
174: }
175:
176: }
|