Exemple #1
0
  public static ParameterSet fromArrayNoCopy(Object... params) {
    byte[][][] encodedStringArrays = new byte[params.length][][];
    byte[][] encodedStrings = new byte[params.length][];

    int size = 2;

    for (int ii = 0; ii < params.length; ii++) {
      Object obj = params[ii];
      if ((obj == null) || (obj == JSONObject.NULL)) {
        size++;
        continue;
      }
      size += 1; // everything has a type even arrays and null
      Class<?> cls = obj.getClass();
      if (cls.isArray()) {

        if (obj instanceof byte[]) {
          final byte[] b = (byte[]) obj;
          size += 4 + b.length;
          continue;
        }

        VoltType type;
        try {
          type = VoltType.typeFromClass(cls.getComponentType());
        } catch (VoltTypeException e) {
          obj = getAKosherArray((Object[]) obj);
          cls = obj.getClass();
          type = VoltType.typeFromClass(cls.getComponentType());
        }

        size += 1 + 2; // component type, array length
        switch (type) {
          case SMALLINT:
            size += 2 * ((short[]) obj).length;
            break;
          case INTEGER:
            size += 4 * ((int[]) obj).length;
            break;
          case BIGINT:
            size += 8 * ((long[]) obj).length;
            break;
          case FLOAT:
            size += 8 * ((double[]) obj).length;
            break;
          case STRING:
            String strings[] = (String[]) obj;
            byte arrayEncodedStrings[][] = new byte[strings.length][];
            for (int zz = 0; zz < strings.length; zz++) {
              if (strings[zz] == null) {
                size += 4;
              } else {
                arrayEncodedStrings[zz] = strings[zz].getBytes(Constants.UTF8ENCODING);
                size += 4 + arrayEncodedStrings[zz].length;
              }
            }
            encodedStringArrays[ii] = arrayEncodedStrings;
            break;
          case TIMESTAMP:
            size += 8 * ((TimestampType[]) obj).length;
            break;
          case DECIMAL:
            size += 16 * ((BigDecimal[]) obj).length;
            break;
          case VOLTTABLE:
            for (VoltTable vt : (VoltTable[]) obj) {
              size += vt.getSerializedSize();
            }
            break;
          case VARBINARY:
            for (byte[] buf : (byte[][]) obj) {
              size += 4; // length prefix
              if (buf != null) {
                size += buf.length;
              }
            }
            break;
          case GEOGRAPHY_POINT:
            size +=
                VoltType.GEOGRAPHY_POINT.getLengthInBytesForFixedTypesWithoutCheck()
                    * ((GeographyPointValue[]) obj).length;
            break;
          case GEOGRAPHY:
            for (GeographyValue gv : (GeographyValue[]) obj) {
              size += 4; // length prefix
              if (gv != null) {
                size += gv.getLengthInBytes();
              }
            }
            break;
          default:
            throw new RuntimeException("FIXME: Unsupported type " + type);
        }
        continue;
      }

      // Handle NULL mappings not encoded by type.min_value convention
      if (obj == VoltType.NULL_TIMESTAMP) {
        size += 8;
        continue;
      } else if (obj == VoltType.NULL_STRING_OR_VARBINARY) {
        size += 4;
        continue;
      } else if (obj == VoltType.NULL_DECIMAL) {
        size += 16;
        continue;
      } else if (obj == VoltType.NULL_POINT) {
        size += VoltType.GEOGRAPHY_POINT.getLengthInBytesForFixedTypesWithoutCheck();
        continue;
      } else if (obj == VoltType.NULL_GEOGRAPHY) {
        size += 4;
        continue;
      } else if (obj instanceof BBContainer) {
        size += 4 + ((BBContainer) obj).b().remaining();
        continue;
      }

      VoltType type = VoltType.typeFromClass(cls);
      switch (type) {
        case TINYINT:
          size++;
          break;
        case SMALLINT:
          size += 2;
          break;
        case INTEGER:
          size += 4;
          break;
        case BIGINT:
          size += 8;
          break;
        case FLOAT:
          size += 8;
          break;
        case STRING:
          byte encodedString[] = ((String) obj).getBytes(Constants.UTF8ENCODING);
          size += 4 + encodedString.length;
          encodedStrings[ii] = encodedString;
          break;
        case TIMESTAMP:
          size += 8;
          break;
        case DECIMAL:
          size += 16;
          break;
        case GEOGRAPHY_POINT:
          size += VoltType.GEOGRAPHY_POINT.getLengthInBytesForFixedTypesWithoutCheck();
          break;
        case GEOGRAPHY:
          size += 4 + ((GeographyValue) obj).getLengthInBytes();
          break;
        case VOLTTABLE:
          size += ((VoltTable) obj).getSerializedSize();
          break;
        default:
          throw new RuntimeException("FIXME: Unsupported type " + type);
      }
    }

    return new ParameterSet(params, size, encodedStrings, encodedStringArrays);
  }
Exemple #2
0
  public void flattenToBuffer(ByteBuffer buf) throws IOException {

    buf.putShort((short) m_params.length);

    for (int i = 0; i < m_params.length; i++) {
      Object obj = m_params[i];
      if ((obj == null) || (obj == JSONObject.NULL)) {
        VoltType type = VoltType.NULL;
        buf.put(type.getValue());
        continue;
      }

      Class<?> cls = obj.getClass();
      if (cls.isArray()) {

        // Since arrays of bytes could be varbinary or strings,
        // and they are the only kind of array needed by the EE,
        // special case them as the VARBINARY type.
        if (obj instanceof byte[]) {
          final byte[] b = (byte[]) obj;
          // commented out this bit... presumably the EE will do this check upon recipt
          /*if (b.length > VoltType.MAX_VALUE_LENGTH) {
              throw new IOException("Value of byte[] larger than allowed max string or varbinary " + VoltType.MAX_VALUE_LENGTH_STR);
          }*/
          buf.put(VoltType.VARBINARY.getValue());
          buf.putInt(b.length);
          buf.put(b);
          continue;
        }

        // Same as before, but deal with the fact it is coming in as a unmanaged bytebuffer
        if (obj instanceof BBContainer) {
          final BBContainer cont = (BBContainer) obj;
          final ByteBuffer paramBuf = cont.b();
          buf.put(VoltType.VARBINARY.getValue());
          buf.putInt(paramBuf.remaining());
          buf.put(paramBuf);
          continue;
        }

        buf.put(ARRAY);

        VoltType type;
        try {
          type = VoltType.typeFromClass(cls.getComponentType());
        } catch (VoltTypeException e) {
          obj = getAKosherArray((Object[]) obj);
          cls = obj.getClass();
          type = VoltType.typeFromClass(cls.getComponentType());
        }

        buf.put(type.getValue());
        switch (type) {
          case SMALLINT:
            SerializationHelper.writeArray((short[]) obj, buf);
            break;
          case INTEGER:
            SerializationHelper.writeArray((int[]) obj, buf);
            break;
          case BIGINT:
            SerializationHelper.writeArray((long[]) obj, buf);
            break;
          case FLOAT:
            SerializationHelper.writeArray((double[]) obj, buf);
            break;
          case STRING:
            if (m_encodedStringArrays[i] == null) {
              // should not happen
              throw new IOException("String array not encoded");
            }
            // This check used to be done by FastSerializer.writeArray(), but things changed?
            if (m_encodedStringArrays[i].length > Short.MAX_VALUE) {
              throw new IOException(
                  "Array exceeds maximum length of " + Short.MAX_VALUE + " bytes");
            }
            buf.putShort((short) m_encodedStringArrays[i].length);
            for (int zz = 0; zz < m_encodedStringArrays[i].length; zz++) {
              SerializationHelper.writeVarbinary(m_encodedStringArrays[i][zz], buf);
            }
            break;
          case TIMESTAMP:
            SerializationHelper.writeArray((TimestampType[]) obj, buf);
            break;
          case DECIMAL:
            // converted long128 in serializer api
            SerializationHelper.writeArray((BigDecimal[]) obj, buf);
            break;
          case VOLTTABLE:
            SerializationHelper.writeArray((VoltTable[]) obj, buf);
            break;
          case VARBINARY:
            SerializationHelper.writeArray((byte[][]) obj, buf);
            break;
          case GEOGRAPHY_POINT:
            SerializationHelper.writeArray((GeographyPointValue[]) obj, buf);
            break;
          case GEOGRAPHY:
            SerializationHelper.writeArray((GeographyValue[]) obj, buf);
            break;
          default:
            throw new RuntimeException("FIXME: Unsupported type " + type);
        }
        continue;
      }

      // Handle NULL mappings not encoded by type.min_value convention
      if (obj == VoltType.NULL_TIMESTAMP) {
        buf.put(VoltType.TIMESTAMP.getValue());
        buf.putLong(VoltType.NULL_BIGINT); // corresponds to EE value.h isNull()
        continue;
      } else if (obj == VoltType.NULL_STRING_OR_VARBINARY) {
        buf.put(VoltType.STRING.getValue());
        buf.putInt(VoltType.NULL_STRING_LENGTH);
        continue;
      } else if (obj == VoltType.NULL_DECIMAL) {
        buf.put(VoltType.DECIMAL.getValue());
        VoltDecimalHelper.serializeNull(buf);
        continue;
      } else if (obj == VoltType.NULL_POINT) {
        buf.put(VoltType.GEOGRAPHY_POINT.getValue());
        GeographyPointValue.serializeNull(buf);
        continue;
      } else if (obj == VoltType.NULL_GEOGRAPHY) {
        buf.put(VoltType.GEOGRAPHY.getValue());
        buf.putInt(VoltType.NULL_STRING_LENGTH);
        continue;
      } else if (obj instanceof BBContainer) {
        final BBContainer cont = (BBContainer) obj;
        final ByteBuffer paramBuf = cont.b();
        buf.put(VoltType.VARBINARY.getValue());
        buf.putInt(paramBuf.remaining());
        buf.put(paramBuf);
        continue;
      }

      VoltType type = VoltType.typeFromClass(cls);
      buf.put(type.getValue());
      switch (type) {
        case TINYINT:
          buf.put((Byte) obj);
          break;
        case SMALLINT:
          buf.putShort((Short) obj);
          break;
        case INTEGER:
          buf.putInt((Integer) obj);
          break;
        case BIGINT:
          buf.putLong((Long) obj);
          break;
        case FLOAT:
          if (cls == Float.class) buf.putDouble(((Float) obj).doubleValue());
          else if (cls == Double.class) buf.putDouble(((Double) obj).doubleValue());
          else throw new RuntimeException("Can't cast parameter type to Double");
          break;
        case STRING:
          if (m_encodedStrings[i] == null) {
            // should not happen
            throw new IOException("String not encoded: " + (String) obj);
          }
          SerializationHelper.writeVarbinary(m_encodedStrings[i], buf);
          break;
        case TIMESTAMP:
          long micros = timestampToMicroseconds(obj);
          buf.putLong(micros);
          break;
        case DECIMAL:
          VoltDecimalHelper.serializeBigDecimal((BigDecimal) obj, buf);
          break;
        case VOLTTABLE:
          ((VoltTable) obj).flattenToBuffer(buf);
          break;
        case GEOGRAPHY_POINT:
          ((GeographyPointValue) obj).flattenToBuffer(buf);
          break;
        case GEOGRAPHY:
          GeographyValue gv = (GeographyValue) obj;
          buf.putInt(gv.getLengthInBytes());
          gv.flattenToBuffer(buf);
          break;
        default:
          throw new RuntimeException("FIXME: Unsupported type " + type);
      }
    }
  }