View Javadoc
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.directory.mavibot.btree.serializer;
21  
22  
23  import java.io.IOException;
24  import java.nio.ByteBuffer;
25  
26  import org.apache.directory.mavibot.btree.comparator.LongArrayComparator;
27  
28  
29  /**
30   * A serializer for a Long[].
31   *
32   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
33   */
34  public class LongArraySerializer extends AbstractElementSerializer<long[]>
35  {
36      /** A static instance of a LongArraySerializer */
37      public static final LongArraySerializer INSTANCE = new LongArraySerializer();
38  
39      /**
40       * Create a new instance of LongSerializer
41       */
42      private LongArraySerializer()
43      {
44          super( LongArrayComparator.INSTANCE );
45      }
46  
47  
48      /**
49       * {@inheritDoc}
50       */
51      public byte[] serialize( long[] element )
52      {
53          int len = -1;
54  
55          if ( element != null )
56          {
57              len = element.length;
58          }
59  
60          byte[] bytes = null;
61          int pos = 0;
62  
63          switch ( len )
64          {
65              case 0:
66                  bytes = new byte[4];
67  
68                  // The number of Long. Here, 0
69                  bytes[pos++] = 0x00;
70                  bytes[pos++] = 0x00;
71                  bytes[pos++] = 0x00;
72                  bytes[pos++] = 0x00;
73  
74                  break;
75  
76              case -1:
77                  bytes = new byte[4];
78  
79                  // The number of Long. Here, null
80                  bytes[pos++] = ( byte ) 0xFF;
81                  bytes[pos++] = ( byte ) 0xFF;
82                  bytes[pos++] = ( byte ) 0xFF;
83                  bytes[pos++] = ( byte ) 0xFF;
84  
85                  break;
86  
87              default:
88                  int dataLen = len * 8 + 4;
89                  bytes = new byte[dataLen];
90  
91                  // The number of longs
92                  bytes[pos++] = ( byte ) ( len >>> 24 );
93                  bytes[pos++] = ( byte ) ( len >>> 16 );
94                  bytes[pos++] = ( byte ) ( len >>> 8 );
95                  bytes[pos++] = ( byte ) ( len );
96  
97                  // Serialize the longs now
98                  for ( long value : element )
99                  {
100                     bytes[pos++] = ( byte ) ( value >>> 56 );
101                     bytes[pos++] = ( byte ) ( value >>> 48 );
102                     bytes[pos++] = ( byte ) ( value >>> 40 );
103                     bytes[pos++] = ( byte ) ( value >>> 32 );
104                     bytes[pos++] = ( byte ) ( value >>> 24 );
105                     bytes[pos++] = ( byte ) ( value >>> 16 );
106                     bytes[pos++] = ( byte ) ( value >>> 8 );
107                     bytes[pos++] = ( byte ) ( value );
108                 }
109         }
110 
111         return bytes;
112     }
113 
114 
115     /**
116      * {@inheritDoc}
117      */
118     public long[] deserialize( BufferHandler bufferHandler ) throws IOException
119     {
120         // Read the DataLength first. Note that we don't use it here.
121         byte[] in = bufferHandler.read( 4 );
122 
123         IntSerializer.deserialize( in );
124 
125         // Now, read the number of Longs
126         in = bufferHandler.read( 4 );
127 
128         int nbLongs = IntSerializer.deserialize( in );
129 
130         switch ( nbLongs )
131         {
132             case 0:
133                 return new long[]
134                     {};
135 
136             case -1:
137                 return null;
138 
139             default:
140                 long[] longs = new long[nbLongs];
141                 in = bufferHandler.read( nbLongs * 8 );
142 
143                 int pos = 0;
144 
145                 for ( int i = 0; i < nbLongs; i++ )
146                 {
147                     longs[i] = ( ( long ) in[pos++] << 56 ) +
148                         ( ( in[pos++] & 0xFFL ) << 48 ) +
149                         ( ( in[pos++] & 0xFFL ) << 40 ) +
150                         ( ( in[pos++] & 0xFFL ) << 32 ) +
151                         ( ( in[pos++] & 0xFFL ) << 24 ) +
152                         ( ( in[pos++] & 0xFFL ) << 16 ) +
153                         ( ( in[pos++] & 0xFFL ) << 8 ) +
154                         ( in[pos++] & 0xFFL );
155                 }
156 
157                 return longs;
158         }
159     }
160 
161 
162     /**
163      * {@inheritDoc}
164      */
165     public long[] deserialize( ByteBuffer buffer ) throws IOException
166     {
167         // Read the dataLength. Note that we don't use it here.
168         buffer.getInt();
169         
170         // The number of longs
171         int nbLongs = buffer.getInt();
172 
173         switch ( nbLongs )
174         {
175             case 0:
176                 return new long[]
177                     {};
178 
179             case -1:
180                 return null;
181 
182             default:
183                 long[] longs = new long[nbLongs];
184 
185                 for ( int i = 0; i < nbLongs; i++ )
186                 {
187                     longs[i] = buffer.getLong();
188                 }
189 
190                 return longs;
191         }
192     }
193 
194 
195     /**
196      * {@inheritDoc}
197      */
198     @Override
199     public int compare( long[] type1, long[] type2 )
200     {
201         if ( type1 == type2 )
202         {
203             return 0;
204         }
205 
206         if ( type1 == null )
207         {
208             if ( type2 == null )
209             {
210                 return 0;
211             }
212             else
213             {
214                 return -1;
215             }
216         }
217         else
218         {
219             if ( type2 == null )
220             {
221                 return 1;
222             }
223             else
224             {
225                 if ( type1.length < type2.length )
226                 {
227                     int pos = 0;
228 
229                     for ( long b1 : type1 )
230                     {
231                         long b2 = type2[pos];
232 
233                         if ( b1 == b2 )
234                         {
235                             pos++;
236                         }
237                         else if ( b1 < b2 )
238                         {
239                             return -1;
240                         }
241                         else
242                         {
243                             return 1;
244                         }
245                     }
246 
247                     return 1;
248                 }
249                 else
250                 {
251                     int pos = 0;
252 
253                     for ( long b2 : type2 )
254                     {
255                         long b1 = type1[pos];
256 
257                         if ( b1 == b2 )
258                         {
259                             pos++;
260                         }
261                         else if ( b1 < b2 )
262                         {
263                             return -1;
264                         }
265                         else
266                         {
267                             return 1;
268                         }
269                     }
270 
271                     return -11;
272                 }
273             }
274         }
275     }
276 
277 
278     @Override
279     public long[] fromBytes( byte[] buffer ) throws IOException
280     {
281         int len = IntSerializer.deserialize( buffer );
282         int pos = 4;
283 
284         switch ( len )
285         {
286             case 0:
287                 return new long[]
288                     {};
289 
290             case -1:
291                 return null;
292 
293             default:
294                 long[] longs = new long[len];
295 
296                 for ( int i = 0; i < len; i++ )
297                 {
298                     longs[i] = LongSerializer.deserialize( buffer, pos );
299                     pos += 8;
300                 }
301 
302                 return longs;
303         }
304     }
305 
306 
307     @Override
308     public long[] fromBytes( byte[] buffer, int pos ) throws IOException
309     {
310         int len = IntSerializer.deserialize( buffer, pos );
311         int newPos = pos + 4;
312 
313         switch ( len )
314         {
315             case 0:
316                 return new long[]
317                     {};
318 
319             case -1:
320                 return null;
321 
322             default:
323                 long[] longs = new long[len];
324 
325                 for ( int i = 0; i < len; i++ )
326                 {
327                     longs[i] = LongSerializer.deserialize( buffer, newPos );
328                     newPos += 8;
329                 }
330 
331                 return longs;
332         }
333     }
334 }