blob: 0822bb43f4168ec62d41424f93ae8a45c23813f2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const Decimal = require('decimal.js');
const Long = require('long');
const ObjectType = require('../ObjectType').ObjectType;
const CompositeType = require('../ObjectType').CompositeType;
const MapObjectType = require('../ObjectType').MapObjectType;
const CollectionObjectType = require('../ObjectType').CollectionObjectType;
const ComplexObjectType = require('../ObjectType').ComplexObjectType;
const ObjectArrayType = require('../ObjectType').ObjectArrayType;
const Timestamp = require('../Timestamp');
const EnumItem = require('../EnumItem');
const Errors = require('../Errors');
const ArgumentChecker = require('./ArgumentChecker');
// Operation codes
const OPERATION = Object.freeze({
// Key-Value Queries
CACHE_GET : 1000,
CACHE_PUT : 1001,
CACHE_PUT_IF_ABSENT : 1002,
CACHE_GET_ALL : 1003,
CACHE_PUT_ALL : 1004,
CACHE_GET_AND_PUT : 1005,
CACHE_GET_AND_REPLACE : 1006,
CACHE_GET_AND_REMOVE : 1007,
CACHE_GET_AND_PUT_IF_ABSENT : 1008,
CACHE_REPLACE : 1009,
CACHE_REPLACE_IF_EQUALS : 1010,
CACHE_CONTAINS_KEY : 1011,
CACHE_CONTAINS_KEYS : 1012,
CACHE_CLEAR : 1013,
CACHE_CLEAR_KEY : 1014,
CACHE_CLEAR_KEYS : 1015,
CACHE_REMOVE_KEY : 1016,
CACHE_REMOVE_IF_EQUALS : 1017,
CACHE_REMOVE_KEYS : 1018,
CACHE_REMOVE_ALL : 1019,
CACHE_GET_SIZE : 1020,
CACHE_LOCAL_PEEK : 1021,
// Cache Configuration
CACHE_GET_NAMES : 1050,
CACHE_CREATE_WITH_NAME : 1051,
CACHE_GET_OR_CREATE_WITH_NAME : 1052,
CACHE_CREATE_WITH_CONFIGURATION : 1053,
CACHE_GET_OR_CREATE_WITH_CONFIGURATION : 1054,
CACHE_GET_CONFIGURATION : 1055,
CACHE_DESTROY : 1056,
CACHE_PARTITIONS : 1101,
// SQL and Scan Queries
QUERY_SCAN : 2000,
QUERY_SCAN_CURSOR_GET_PAGE : 2001,
QUERY_SQL : 2002,
QUERY_SQL_CURSOR_GET_PAGE : 2003,
QUERY_SQL_FIELDS : 2004,
QUERY_SQL_FIELDS_CURSOR_GET_PAGE : 2005,
RESOURCE_CLOSE : 0,
// Binary Types
GET_BINARY_TYPE : 3002,
PUT_BINARY_TYPE : 3003
});
const TYPE_CODE = Object.assign({
BINARY_OBJECT : 27,
BINARY_ENUM : 38
},
ObjectType.PRIMITIVE_TYPE,
ObjectType.COMPOSITE_TYPE);
const TYPE_INFO = Object.freeze({
[TYPE_CODE.BYTE] : {
NAME : 'byte',
SIZE : 1
},
[TYPE_CODE.SHORT] : {
NAME : 'short',
SIZE : 2
},
[TYPE_CODE.INTEGER] : {
NAME : 'integer',
SIZE : 4
},
[TYPE_CODE.LONG] : {
NAME : 'long',
SIZE : 8
},
[TYPE_CODE.FLOAT] : {
NAME : 'float',
SIZE : 4
},
[TYPE_CODE.DOUBLE] : {
NAME : 'double',
SIZE : 8
},
[TYPE_CODE.CHAR] : {
NAME : 'char',
SIZE : 2
},
[TYPE_CODE.BOOLEAN] : {
NAME : 'boolean',
SIZE : 1
},
[TYPE_CODE.STRING] : {
NAME : 'string',
NULLABLE : true
},
[TYPE_CODE.UUID] : {
NAME : 'UUID',
SIZE : 16,
NULLABLE : true
},
[TYPE_CODE.DATE] : {
NAME : 'date',
SIZE : 8,
NULLABLE : true
},
[TYPE_CODE.BYTE_ARRAY] : {
NAME : 'byte array',
ELEMENT_TYPE : TYPE_CODE.BYTE,
NULLABLE : true
},
[TYPE_CODE.SHORT_ARRAY] : {
NAME : 'short array',
ELEMENT_TYPE : TYPE_CODE.SHORT,
NULLABLE : true
},
[TYPE_CODE.INTEGER_ARRAY] : {
NAME : 'integer array',
ELEMENT_TYPE : TYPE_CODE.INTEGER,
NULLABLE : true
},
[TYPE_CODE.LONG_ARRAY] : {
NAME : 'long array',
ELEMENT_TYPE : TYPE_CODE.LONG,
NULLABLE : true
},
[TYPE_CODE.FLOAT_ARRAY] : {
NAME : 'float array',
ELEMENT_TYPE : TYPE_CODE.FLOAT,
NULLABLE : true
},
[TYPE_CODE.DOUBLE_ARRAY] : {
NAME : 'double array',
ELEMENT_TYPE : TYPE_CODE.DOUBLE,
NULLABLE : true
},
[TYPE_CODE.CHAR_ARRAY] : {
NAME : 'char array',
ELEMENT_TYPE : TYPE_CODE.CHAR,
NULLABLE : true
},
[TYPE_CODE.BOOLEAN_ARRAY] : {
NAME : 'boolean array',
ELEMENT_TYPE : TYPE_CODE.BOOLEAN,
NULLABLE : true
},
[TYPE_CODE.STRING_ARRAY] : {
NAME : 'string array',
ELEMENT_TYPE : TYPE_CODE.STRING,
KEEP_ELEMENT_TYPE : true,
NULLABLE : true
},
[TYPE_CODE.DATE_ARRAY] : {
NAME : 'date array',
ELEMENT_TYPE : TYPE_CODE.DATE,
KEEP_ELEMENT_TYPE : true,
NULLABLE : true
},
[TYPE_CODE.UUID_ARRAY] : {
NAME : 'UUID array',
ELEMENT_TYPE : TYPE_CODE.UUID,
KEEP_ELEMENT_TYPE : true,
NULLABLE : true
},
[TYPE_CODE.OBJECT_ARRAY] : {
NAME : 'object array',
ELEMENT_TYPE : TYPE_CODE.COMPLEX_OBJECT,
KEEP_ELEMENT_TYPE : true,
NULLABLE : true
},
[TYPE_CODE.COLLECTION] : {
NAME : 'collection',
NULLABLE : true
},
[TYPE_CODE.MAP] : {
NAME : 'map',
NULLABLE : true
},
[TYPE_CODE.BINARY_OBJECT] : {
NAME : 'BinaryObject',
NULLABLE : true
},
[TYPE_CODE.ENUM] : {
NAME : 'enum',
NULLABLE : true
},
[TYPE_CODE.ENUM_ARRAY] : {
NAME : 'enum array',
ELEMENT_TYPE : TYPE_CODE.ENUM,
KEEP_ELEMENT_TYPE : true,
NULLABLE : true
},
[TYPE_CODE.DECIMAL] : {
NAME : 'decimal',
NULLABLE : true
},
[TYPE_CODE.DECIMAL_ARRAY] : {
NAME : 'decimal array',
ELEMENT_TYPE : TYPE_CODE.DECIMAL,
KEEP_ELEMENT_TYPE : true,
NULLABLE : true
},
[TYPE_CODE.TIMESTAMP] : {
NAME : 'timestamp',
NULLABLE : true
},
[TYPE_CODE.TIMESTAMP_ARRAY] : {
NAME : 'timestamp array',
ELEMENT_TYPE : TYPE_CODE.TIMESTAMP,
KEEP_ELEMENT_TYPE : true,
NULLABLE : true
},
[TYPE_CODE.TIME] : {
NAME : 'time',
NULLABLE : true
},
[TYPE_CODE.TIME_ARRAY] : {
NAME : 'time array',
ELEMENT_TYPE : TYPE_CODE.TIME,
KEEP_ELEMENT_TYPE : true,
NULLABLE : true
},
[TYPE_CODE.NULL] : {
NAME : 'null',
NULLABLE : true
},
[TYPE_CODE.COMPLEX_OBJECT] : {
NAME : 'complex object',
NULLABLE : true
}
});
const UTF8_ENCODING = 'utf8';
class BinaryUtils {
static get OPERATION() {
return OPERATION;
}
static get TYPE_CODE() {
return TYPE_CODE;
}
static get TYPE_INFO() {
return TYPE_INFO;
}
static getSize(typeCode) {
const size = TYPE_INFO[typeCode].SIZE;
return size ? size : 0;
}
static get ENCODING() {
return UTF8_ENCODING;
}
static getTypeName(type) {
if (typeof type === 'string') {
return type;
}
const typeCode = BinaryUtils.getTypeCode(type);
return TYPE_INFO[typeCode] ? TYPE_INFO[typeCode].NAME : 'type code ' + typeCode;
}
static isNullable(type) {
return TYPE_INFO[BinaryUtils.getTypeCode(type)].NULLABLE === true;
}
static getTypeCode(type) {
return type instanceof CompositeType ? type._typeCode : type;
}
static checkObjectType(type, argName) {
if (type === null || type instanceof CompositeType) {
return;
}
ArgumentChecker.hasValueFrom(type, argName, false, ObjectType.PRIMITIVE_TYPE);
}
static calcObjectType(object) {
const BinaryObject = require('../BinaryObject');
const objectType = typeof object;
if (object === null) {
throw Errors.IgniteClientError.unsupportedTypeError(BinaryUtils.TYPE_CODE.NULL);
}
else if (objectType === 'number') {
return BinaryUtils.TYPE_CODE.DOUBLE;
}
else if (objectType === 'string') {
return BinaryUtils.TYPE_CODE.STRING;
}
else if (objectType === 'boolean') {
return BinaryUtils.TYPE_CODE.BOOLEAN;
}
else if (object instanceof Timestamp) {
return BinaryUtils.TYPE_CODE.TIMESTAMP;
}
else if (object instanceof Date) {
return BinaryUtils.TYPE_CODE.DATE;
}
else if (object instanceof EnumItem) {
return BinaryUtils.TYPE_CODE.ENUM;
}
else if (object instanceof Decimal) {
return BinaryUtils.TYPE_CODE.DECIMAL;
}
else if (object instanceof Array) {
if (object.length > 0 && object[0] !== null) {
return BinaryUtils.getArrayType(BinaryUtils.calcObjectType(object[0]));
}
}
else if (object instanceof Set) {
return new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.HASH_SET);
}
else if (object instanceof Map) {
return new MapObjectType();
}
else if (object instanceof BinaryObject) {
return BinaryUtils.TYPE_CODE.BINARY_OBJECT;
}
else if (objectType === 'object') {
return new ComplexObjectType(object);
}
throw Errors.IgniteClientError.unsupportedTypeError(objectType);
}
static checkCompatibility(value, type) {
if (!type) {
return;
}
const typeCode = BinaryUtils.getTypeCode(type);
if (value === null) {
if (!BinaryUtils.isNullable(typeCode)) {
throw Errors.IgniteClientError.typeCastError(BinaryUtils.TYPE_CODE.NULL, typeCode);
}
return;
}
else if (BinaryUtils.isStandardType(typeCode)) {
BinaryUtils.checkStandardTypeCompatibility(value, typeCode, type);
return;
}
const valueTypeCode = BinaryUtils.getTypeCode(BinaryUtils.calcObjectType(value));
if (typeCode !== valueTypeCode) {
throw Errors.IgniteClientError.typeCastError(valueTypeCode, typeCode);
}
}
static isStandardType(typeCode) {
return typeCode !== BinaryUtils.TYPE_CODE.BINARY_OBJECT &&
typeCode !== BinaryUtils.TYPE_CODE.COMPLEX_OBJECT;
}
static checkStandardTypeCompatibility(value, typeCode, type = null) {
const valueType = typeof value;
switch (typeCode) {
case BinaryUtils.TYPE_CODE.BYTE:
case BinaryUtils.TYPE_CODE.SHORT:
case BinaryUtils.TYPE_CODE.INTEGER:
case BinaryUtils.TYPE_CODE.LONG:
if (!Number.isInteger(value)) {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.FLOAT:
case BinaryUtils.TYPE_CODE.DOUBLE:
if (valueType !== 'number') {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.CHAR:
if (valueType !== 'string' || value.length !== 1) {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.BOOLEAN:
if (valueType !== 'boolean') {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.STRING:
if (valueType !== 'string') {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.UUID:
if (!value instanceof Array ||
value.length !== BinaryUtils.getSize(BinaryUtils.TYPE_CODE.UUID)) {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
value.forEach(element =>
BinaryUtils.checkStandardTypeCompatibility(element, BinaryUtils.TYPE_CODE.BYTE));
return;
case BinaryUtils.TYPE_CODE.DATE:
if (!value instanceof Date) {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.ENUM:
if (!value instanceof EnumItem) {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.DECIMAL:
if (!value instanceof Decimal) {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.TIMESTAMP:
if (!value instanceof Timestamp) {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.TIME:
if (!value instanceof Date) {
throw Errors.IgniteClientError.valueCastError(value, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.BYTE_ARRAY:
case BinaryUtils.TYPE_CODE.SHORT_ARRAY:
case BinaryUtils.TYPE_CODE.INTEGER_ARRAY:
case BinaryUtils.TYPE_CODE.LONG_ARRAY:
case BinaryUtils.TYPE_CODE.FLOAT_ARRAY:
case BinaryUtils.TYPE_CODE.DOUBLE_ARRAY:
case BinaryUtils.TYPE_CODE.CHAR_ARRAY:
case BinaryUtils.TYPE_CODE.BOOLEAN_ARRAY:
case BinaryUtils.TYPE_CODE.STRING_ARRAY:
case BinaryUtils.TYPE_CODE.UUID_ARRAY:
case BinaryUtils.TYPE_CODE.DATE_ARRAY:
case BinaryUtils.TYPE_CODE.OBJECT_ARRAY:
case BinaryUtils.TYPE_CODE.ENUM_ARRAY:
case BinaryUtils.TYPE_CODE.DECIMAL_ARRAY:
case BinaryUtils.TYPE_CODE.TIMESTAMP_ARRAY:
case BinaryUtils.TYPE_CODE.TIME_ARRAY:
if (!value instanceof Array) {
throw Errors.IgniteClientError.typeCastError(valueType, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.MAP:
if (!value instanceof Map) {
throw Errors.IgniteClientError.typeCastError(valueType, typeCode);
}
return;
case BinaryUtils.TYPE_CODE.COLLECTION:
if (!(type && type._isSet() && value instanceof Set || value instanceof Array)) {
throw Errors.IgniteClientError.typeCastError(valueType, type && type._isSet() ? 'set' : typeCode);
}
return;
case BinaryUtils.TYPE_CODE.NULL:
if (value !== null) {
throw Errors.IgniteClientError.typeCastError('not null', typeCode);
}
return;
default:
const valueTypeCode = BinaryUtils.getTypeCode(BinaryUtils.calcObjectType(value));
if (valueTypeCode === BinaryUtils.TYPE_CODE.BINARY_OBJECT) {
throw Errors.IgniteClientError.typeCastError(valueTypeCode, typeCode);
}
return;
}
}
static checkTypesComatibility(expectedType, actualTypeCode) {
if (expectedType === null) {
return;
}
const expectedTypeCode = BinaryUtils.getTypeCode(expectedType);
if (actualTypeCode === BinaryUtils.TYPE_CODE.NULL) {
return;
}
else if (expectedTypeCode === BinaryUtils.TYPE_CODE.BINARY_OBJECT ||
actualTypeCode === BinaryUtils.TYPE_CODE.BINARY_OBJECT &&
expectedTypeCode === BinaryUtils.TYPE_CODE.COMPLEX_OBJECT) {
return;
}
else if (expectedTypeCode === BinaryUtils.TYPE_CODE.ENUM &&
actualTypeCode === BinaryUtils.TYPE_CODE.BINARY_ENUM) {
return;
}
else if (actualTypeCode !== expectedTypeCode) {
throw Errors.IgniteClientError.typeCastError(actualTypeCode, expectedTypeCode);
}
}
static getArrayElementType(arrayType) {
if (arrayType instanceof ObjectArrayType) {
return arrayType._elementType;
}
else if (arrayType === BinaryUtils.TYPE_CODE.OBJECT_ARRAY) {
return null;
}
const elementTypeCode = TYPE_INFO[arrayType].ELEMENT_TYPE;
if (!elementTypeCode) {
throw Errors.IgniteClientError.internalError();
}
return elementTypeCode;
}
static getArrayType(elementType) {
switch (BinaryUtils.getTypeCode(elementType)) {
case BinaryUtils.TYPE_CODE.BYTE:
return BinaryUtils.TYPE_CODE.BYTE_ARRAY;
case BinaryUtils.TYPE_CODE.SHORT:
return BinaryUtils.TYPE_CODE.SHORT_ARRAY;
case BinaryUtils.TYPE_CODE.INTEGER:
return BinaryUtils.TYPE_CODE.INTEGER_ARRAY;
case BinaryUtils.TYPE_CODE.LONG:
return BinaryUtils.TYPE_CODE.LONG_ARRAY;
case BinaryUtils.TYPE_CODE.FLOAT:
return BinaryUtils.TYPE_CODE.FLOAT_ARRAY;
case BinaryUtils.TYPE_CODE.DOUBLE:
return BinaryUtils.TYPE_CODE.DOUBLE_ARRAY;
case BinaryUtils.TYPE_CODE.CHAR:
return BinaryUtils.TYPE_CODE.CHAR_ARRAY;
case BinaryUtils.TYPE_CODE.BOOLEAN:
return BinaryUtils.TYPE_CODE.BOOLEAN_ARRAY;
case BinaryUtils.TYPE_CODE.STRING:
return BinaryUtils.TYPE_CODE.STRING_ARRAY;
case BinaryUtils.TYPE_CODE.UUID:
return BinaryUtils.TYPE_CODE.UUID_ARRAY;
case BinaryUtils.TYPE_CODE.DATE:
return BinaryUtils.TYPE_CODE.DATE_ARRAY;
case BinaryUtils.TYPE_CODE.ENUM:
return BinaryUtils.TYPE_CODE.ENUM_ARRAY;
case BinaryUtils.TYPE_CODE.DECIMAL:
return BinaryUtils.TYPE_CODE.DECIMAL_ARRAY;
case BinaryUtils.TYPE_CODE.TIMESTAMP:
return BinaryUtils.TYPE_CODE.TIMESTAMP_ARRAY;
case BinaryUtils.TYPE_CODE.TIME:
return BinaryUtils.TYPE_CODE.TIME_ARRAY;
case BinaryUtils.TYPE_CODE.BINARY_OBJECT:
return new ObjectArrayType();
default:
return new ObjectArrayType(elementType);
}
}
static keepArrayElementType(arrayTypeCode) {
return TYPE_INFO[arrayTypeCode].KEEP_ELEMENT_TYPE === true;
}
static getJsObjectFieldNames(jsObject) {
var fields = new Array();
for (let field in jsObject) {
if (typeof jsObject[field] !== 'function') {
fields.push(field);
}
}
return fields;
}
static async hashCode(object, communicator, typeCode = null) {
if (typeCode === null) {
typeCode = BinaryUtils.getTypeCode(BinaryUtils.calcObjectType(object));
}
if (BinaryUtils.isStandardType(typeCode)) {
return BinaryUtils.standardHashCode(object, typeCode);
}
else {
return await object._getHashCode(communicator);
}
}
// Calculates hash code for an object of a standard type
static standardHashCode(object, typeCode = null) {
if (typeCode === null) {
typeCode = BinaryUtils.getTypeCode(BinaryUtils.calcObjectType(object));
}
switch (typeCode) {
case BinaryUtils.TYPE_CODE.BYTE:
case BinaryUtils.TYPE_CODE.SHORT:
case BinaryUtils.TYPE_CODE.INTEGER:
return this.intHashCode(object);
case BinaryUtils.TYPE_CODE.LONG:
return this.longHashCode(object);
case BinaryUtils.TYPE_CODE.FLOAT:
return this.floatHashCode(object);
case BinaryUtils.TYPE_CODE.DOUBLE:
return this.doubleHashCode(object);
case BinaryUtils.TYPE_CODE.CHAR:
return this.charHashCode(object);
case BinaryUtils.TYPE_CODE.BOOLEAN:
return this.boolHashCode(object);
case BinaryUtils.TYPE_CODE.STRING:
return this.strHashCode(object);
case BinaryUtils.TYPE_CODE.UUID:
return this.uuidHashCode(object);
case BinaryUtils.TYPE_CODE.TIME:
return this.timeHashCode(object);
case BinaryUtils.TYPE_CODE.DATE:
case BinaryUtils.TYPE_CODE.TIMESTAMP:
return this.datetimeHashCode(object);
default:
return 0;
}
}
static contentHashCode(buffer, startPos, endPos) {
let hash = 1;
for (let i = startPos; i <= endPos; i++) {
hash = 31 * hash + buffer._buffer[i];
hash |= 0; // Convert to 32bit integer
}
return hash;
}
static strHashCode(str) {
// This method calcuates hash code for the String Ignite type
// bool must be a js 'string'
let hash = 0, char;
if (str && str.length > 0) {
for (let i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash |= 0; // Convert to 32bit integer
}
}
return hash;
}
static strHashCodeLowerCase(str) {
return BinaryUtils.strHashCode(str ? str.toLowerCase() : str);
}
static charHashCode(char) {
// This method calcuates hash code for the Char Ignite type
// char must be a js 'string' of length 1
return char.charCodeAt(0);
}
static intHashCode(int) {
// This method calcuates hash code for Byte, Short or Integer Ignite types
// int must be a js 'number'
return int;
}
static longHashCode(long) {
// This method calcuates hash code for the Long Ignite type
// long must be a js 'number'
const longObj = Long.fromNumber(long);
return longObj.getLowBits() ^ longObj.getHighBits();
}
static boolHashCode(bool) {
// This method calcuates hash code for the Boolean Ignite type
// bool must be a js 'boolean'
return bool ? 1231 : 1237;
}
static floatHashCode(float) {
// This method calcuates hash code for the Float Ignite type
// float must be a js 'number'
const buf = new ArrayBuffer(4);
(new Float32Array(buf))[0] = float;
const int32arr = new Int32Array(buf);
return int32arr[0];
}
static doubleHashCode(double) {
// This method calcuates hash code for the Double Ignite type
// double must be a js 'number'
const buf = new ArrayBuffer(8);
(new Float64Array(buf))[0] = double;
const uint32arr = new Uint32Array(buf);
return uint32arr[0] ^ uint32arr[1];
}
static uuidHashCode(uuid) {
// This method calcuates hash code for the UUID Ignite type
// uuid must be a js Array of 'number' of length 16
const buf = Buffer.from(uuid);
let xor = 0;
for (let i = 0; i < 16; i += 4) {
xor ^= buf.readUInt32BE(i);
}
return xor;
}
static timeHashCode(time) {
// This method calcuates hash code for the Time Ignite type
// time must be an instance of Date
const midnight = new Date(time);
midnight.setHours(0, 0, 0, 0);
const totalmsec = time.getTime() - midnight.getTime();
return BinaryUtils.longHashCode(totalmsec);
}
static datetimeHashCode(date) {
// This method calcuates hash code for the Timestamp and Date Ignite types
// date must be an instance of Date or Timestamp
return BinaryUtils.longHashCode(date.getTime());
}
}
module.exports = BinaryUtils;