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 007 * "License"); you may not use this file except in compliance 008 * with the License. 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, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.mavibot.btree.serializer; 021 022 023import java.io.IOException; 024import java.nio.ByteBuffer; 025 026import org.apache.directory.mavibot.btree.comparator.LongArrayComparator; 027 028 029/** 030 * A serializer for a Long[]. 031 * 032 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 033 */ 034public class LongArraySerializer extends AbstractElementSerializer<long[]> 035{ 036 /** A static instance of a LongArraySerializer */ 037 public static final LongArraySerializer INSTANCE = new LongArraySerializer(); 038 039 /** 040 * Create a new instance of LongSerializer 041 */ 042 private LongArraySerializer() 043 { 044 super( LongArrayComparator.INSTANCE ); 045 } 046 047 048 /** 049 * {@inheritDoc} 050 */ 051 public byte[] serialize( long[] element ) 052 { 053 int len = -1; 054 055 if ( element != null ) 056 { 057 len = element.length; 058 } 059 060 byte[] bytes = null; 061 int pos = 0; 062 063 switch ( len ) 064 { 065 case 0: 066 bytes = new byte[4]; 067 068 // The number of Long. Here, 0 069 bytes[pos++] = 0x00; 070 bytes[pos++] = 0x00; 071 bytes[pos++] = 0x00; 072 bytes[pos++] = 0x00; 073 074 break; 075 076 case -1: 077 bytes = new byte[4]; 078 079 // The number of Long. Here, null 080 bytes[pos++] = ( byte ) 0xFF; 081 bytes[pos++] = ( byte ) 0xFF; 082 bytes[pos++] = ( byte ) 0xFF; 083 bytes[pos++] = ( byte ) 0xFF; 084 085 break; 086 087 default: 088 int dataLen = len * 8 + 4; 089 bytes = new byte[dataLen]; 090 091 // The number of longs 092 bytes[pos++] = ( byte ) ( len >>> 24 ); 093 bytes[pos++] = ( byte ) ( len >>> 16 ); 094 bytes[pos++] = ( byte ) ( len >>> 8 ); 095 bytes[pos++] = ( byte ) ( len ); 096 097 // Serialize the longs now 098 for ( long value : element ) 099 { 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}