001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: ObjectArray.java 468638 2006-10-28 06:52:06Z minchau $
020     */
021    package org.apache.xalan.lib.sql;
022    
023    import java.util.Vector;
024    
025    /**
026     * Provide a simple Array storage mechinsim where  native Arrays will be use as
027     * the basic storage mechinism but the Arrays will be stored as blocks.
028     * The size of the Array blocks is determine during object construction.
029     * This is intended to be a simple storage mechinsim where the storage only
030     * can grow. Array elements can not be removed, only added to.
031     */
032    public class ObjectArray
033    {
034      /**
035       */
036      private int m_minArraySize = 10;
037      /**
038       * The container of all the sub arrays
039       */
040      private Vector m_Arrays = new Vector(200);
041    
042      /**
043       * An index that porvides the Vector entry for the current Array that is
044       * being appended to.
045       */
046      private _ObjectArray m_currentArray;
047    
048    
049      /**
050       * The next offset in the current Array to append a new object
051       */
052      private int m_nextSlot;
053    
054    
055      /**
056       */
057      public ObjectArray( )
058      {
059        //
060        // Default constructor will work with a minimal fixed size
061        //
062        init(10);
063      }
064    
065      /**
066       * @param minArraySize The size of the Arrays stored in the Vector
067       */
068      public ObjectArray( final int minArraySize )
069      {
070        init(minArraySize);
071      }
072    
073      /**
074       * @param size
075       *
076       */
077      private void init( int size )
078      {
079        m_minArraySize = size;
080        m_currentArray = new _ObjectArray(m_minArraySize);
081      }
082    
083      /**
084       * @param idx Index of the Object in the Array
085       *
086       */
087      public Object getAt( final int idx )
088      {
089        int arrayIndx = idx / m_minArraySize;
090        int arrayOffset = idx - (arrayIndx * m_minArraySize);
091    
092        //
093        // If the array has been off loaded to the Vector Storage them
094        // grab it from there.
095        if (arrayIndx < m_Arrays.size())
096        {
097          _ObjectArray a = (_ObjectArray)m_Arrays.elementAt(arrayIndx);
098          return a.objects[arrayOffset];
099        }
100        else
101        {
102          // We must be in the current array, so pull it from there
103    
104          // %REVIEW% We may want to check to see if arrayIndx is only
105          // one freater that the m_Arrays.size(); This code is safe but
106          // will repete if the index is greater than the array size.
107          return m_currentArray.objects[arrayOffset];
108        }
109      }
110    
111      /**
112       * @param idx Index of the Object in the Array
113       * @param obj , The value to set in the Array
114       *
115       */
116      public void setAt( final int idx, final Object obj )
117      {
118        int arrayIndx = idx / m_minArraySize;
119        int arrayOffset = idx - (arrayIndx * m_minArraySize);
120    
121        //
122        // If the array has been off loaded to the Vector Storage them
123        // grab it from there.
124        if (arrayIndx < m_Arrays.size())
125        {
126          _ObjectArray a = (_ObjectArray)m_Arrays.elementAt(arrayIndx);
127          a.objects[arrayOffset] = obj;
128        }
129        else
130        {
131          // We must be in the current array, so pull it from there
132    
133          // %REVIEW% We may want to check to see if arrayIndx is only
134          // one freater that the m_Arrays.size(); This code is safe but
135          // will repete if the index is greater than the array size.
136          m_currentArray.objects[arrayOffset] = obj;
137        }
138      }
139    
140    
141    
142      /**
143       * @param o Object to be appended to the Array
144       *
145       */
146      public int append( Object o )
147      {
148        if (m_nextSlot >= m_minArraySize)
149        {
150          m_Arrays.addElement(m_currentArray);
151          m_nextSlot = 0;
152          m_currentArray = new _ObjectArray(m_minArraySize);
153        }
154    
155        m_currentArray.objects[m_nextSlot] = o;
156    
157        int pos = (m_Arrays.size() * m_minArraySize) + m_nextSlot;
158    
159        m_nextSlot++;
160    
161        return pos;
162      }
163    
164    
165      /**
166       */
167      class _ObjectArray
168      {
169        /**
170         */
171        public Object[] objects;
172        /**
173         * @param size
174         */
175        public _ObjectArray( int size )
176        {
177          objects = new Object[size];
178        }
179      }
180    
181      /**
182       * @param args
183       *
184       */
185      public static void main( String[] args )
186      {
187        String[] word={
188          "Zero","One","Two","Three","Four","Five",
189          "Six","Seven","Eight","Nine","Ten",
190          "Eleven","Twelve","Thirteen","Fourteen","Fifteen",
191          "Sixteen","Seventeen","Eighteen","Nineteen","Twenty",
192          "Twenty-One","Twenty-Two","Twenty-Three","Twenty-Four",
193          "Twenty-Five","Twenty-Six","Twenty-Seven","Twenty-Eight",
194          "Twenty-Nine","Thirty","Thirty-One","Thirty-Two",
195          "Thirty-Three","Thirty-Four","Thirty-Five","Thirty-Six",
196          "Thirty-Seven","Thirty-Eight","Thirty-Nine"};
197    
198        ObjectArray m_ObjectArray = new ObjectArray();
199        // Add them in, using the default block size
200        for (int x =0; x< word.length; x++)
201        {
202          System.out.print(" - " + m_ObjectArray.append(word[x]));
203        }
204    
205        System.out.println("\n");
206        // Now let's read them out sequentally
207        for (int x =0; x< word.length; x++)
208        {
209          String s = (String) m_ObjectArray.getAt(x);
210          System.out.println(s);
211        }
212    
213        // Some Random Access
214        System.out.println((String) m_ObjectArray.getAt(5));
215        System.out.println((String) m_ObjectArray.getAt(10));
216        System.out.println((String) m_ObjectArray.getAt(20));
217        System.out.println((String) m_ObjectArray.getAt(2));
218        System.out.println((String) m_ObjectArray.getAt(15));
219        System.out.println((String) m_ObjectArray.getAt(30));
220        System.out.println((String) m_ObjectArray.getAt(6));
221        System.out.println((String) m_ObjectArray.getAt(8));
222    
223        // Out of bounds
224        System.out.println((String) m_ObjectArray.getAt(40));
225    
226      }
227    }