Skip to content

Commit

Permalink
Native BigInt (#890)
Browse files Browse the repository at this point in the history
  • Loading branch information
CarsonF committed Apr 8, 2024
1 parent d6f3f56 commit 5dd3fa9
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 392 deletions.
84 changes: 35 additions & 49 deletions packages/driver/src/codecs/datetime.ts
Expand Up @@ -18,7 +18,6 @@

import { ReadBuffer, WriteBuffer } from "../primitives/buffer";
import { ICodec, ScalarCodec } from "./ifaces";
import * as bi from "../primitives/bigint";
import {
LocalDateTime,
LocalDate,
Expand Down Expand Up @@ -77,34 +76,32 @@ export class LocalDateTimeCodec extends ScalarCodec implements ICodec {
);
}

const ms = bi.make(localDateInstances.get(object)!.getTime() - TIMESHIFT);
let us = bi.add(
bi.mul(ms, bi.make(1000)),
bi.make(
object.hour * 3_600_000_000 +
object.minute * 60_000_000 +
object.second * 1_000_000 +
object.millisecond * 1000 +
const ms = BigInt(localDateInstances.get(object)!.getTime() - TIMESHIFT);
let us =
ms * 1000n +
BigInt(
object.hour * 36e8 +
object.minute * 6e7 +
object.second * 1e6 +
object.millisecond * 1e3 +
object.microsecond
)
);
);

if (
(object.nanosecond === 500 && Math.abs(object.microsecond) % 2 === 1) ||
object.nanosecond > 500
) {
us = bi.add(us, bi.make(1));
us += 1n;
}

buf.writeInt32(8);
buf.writeBigInt64(us as bigint);
}

decode(buf: ReadBuffer): LocalDateTime {
const bi1000 = bi.make(1000);
const bi_us = buf.readBigInt64();
const bi_ms = bi.div(bi_us, bi1000);
let us = Number(bi.sub(bi_us, bi.mul(bi_ms, bi1000)));
const bi_ms = bi_us / 1000n;
let us = Number(bi_us - bi_ms * 1000n);
let ms = Number(bi_ms);
if (us < 0) {
us += 1000;
Expand Down Expand Up @@ -217,38 +214,26 @@ export class DurationCodec extends ScalarCodec implements ICodec {
);
}

let us = bi.make(Math.abs(object.microseconds));
us = bi.add(
us,
bi.mul(bi.make(Math.abs(object.milliseconds)), bi.make(1_000))
);
us = bi.add(
us,
bi.mul(bi.make(Math.abs(object.seconds)), bi.make(1_000_000))
);
us = bi.add(
us,
bi.mul(bi.make(Math.abs(object.minutes)), bi.make(60_000_000))
);
us = bi.add(
us,
bi.mul(bi.make(Math.abs(object.hours)), bi.make(3_600_000_000))
);
let us = BigInt(Math.abs(object.microseconds));
us += BigInt(Math.abs(object.milliseconds)) * BigInt(1e3);
us += BigInt(Math.abs(object.seconds)) * BigInt(1e6);
us += BigInt(Math.abs(object.minutes)) * BigInt(6e7);
us += BigInt(Math.abs(object.hours)) * BigInt(36e8);

if (
(Math.abs(object.nanoseconds) === 500 &&
Math.abs(object.microseconds) % 2 === 1) ||
Math.abs(object.nanoseconds) > 500
) {
us = bi.add(us, bi.make(1));
us += 1n;
}

if (object.sign < 0) {
us = bi.mul(us, bi.make(-1));
us *= -1n;
}

buf.writeInt32(16);
buf.writeBigInt64(us as bigint);
buf.writeBigInt64(us);
buf.writeInt32(0);
buf.writeInt32(0);
}
Expand All @@ -267,13 +252,13 @@ export class DurationCodec extends ScalarCodec implements ICodec {
let sign = 1;
if (Number(bius) < 0) {
sign = -1;
bius = bi.mul(bi.make(-1), bius);
bius *= -1n;
}

const biMillion = bi.make(1_000_000);
const biMillion = 1_000_000n;

const biSeconds = bi.div(bius, biMillion);
let us = Number(bi.sub(bius, bi.mul(biSeconds, biMillion)));
const biSeconds = bius / biMillion;
let us = Number(bius - biSeconds * biMillion);
const ms = Math.floor(us / 1000);
us = us % 1000;

Expand Down Expand Up @@ -307,14 +292,15 @@ export class RelativeDurationCodec extends ScalarCodec implements ICodec {
`);
}

let us = bi.make(object.microseconds);
us = bi.add(us, bi.mul(bi.make(object.milliseconds), bi.make(1_000)));
us = bi.add(us, bi.mul(bi.make(object.seconds), bi.make(1_000_000)));
us = bi.add(us, bi.mul(bi.make(object.minutes), bi.make(60_000_000)));
us = bi.add(us, bi.mul(bi.make(object.hours), bi.make(3_600_000_000)));
const us =
BigInt(object.microseconds) +
BigInt(object.milliseconds) * BigInt(1e3) +
BigInt(object.seconds) * BigInt(1e6) +
BigInt(object.minutes) * BigInt(6e7) +
BigInt(object.hours) * BigInt(36e8);

buf.writeInt32(16);
buf.writeBigInt64(us as bigint);
buf.writeBigInt64(us);
buf.writeInt32(object.days + 7 * object.weeks);
buf.writeInt32(object.months + 12 * object.years);
}
Expand All @@ -327,13 +313,13 @@ export class RelativeDurationCodec extends ScalarCodec implements ICodec {
let sign = 1;
if (Number(bius) < 0) {
sign = -1;
bius = bi.mul(bi.make(-1), bius);
bius *= -1n;
}

const biMillion = bi.make(1_000_000);
const million = BigInt(1e6);

const biSeconds = bi.div(bius, biMillion);
let us = Number(bi.sub(bius, bi.mul(biSeconds, biMillion)));
const biSeconds = bius / million;
let us = Number(bius - biSeconds * million);
const ms = Math.trunc(us / 1000);
us = us % 1000;

Expand Down
3 changes: 1 addition & 2 deletions packages/driver/src/codecs/numbers.ts
Expand Up @@ -17,7 +17,6 @@
*/

import { ReadBuffer, WriteBuffer } from "../primitives/buffer";
import * as bi from "../primitives/bigint";
import { ICodec, ScalarCodec } from "./ifaces";
import { InvalidArgumentError } from "../errors";

Expand All @@ -38,7 +37,7 @@ export class Int64Codec extends ScalarCodec implements ICodec {

export class Int64BigintCodec extends ScalarCodec implements ICodec {
encode(buf: WriteBuffer, object: any): void {
if (!bi.isBigInt(object)) {
if (typeof object !== "bigint") {
throw new InvalidArgumentError(`a bigint was expected, got "${object}"`);
}
buf.writeInt32(8);
Expand Down
82 changes: 0 additions & 82 deletions packages/driver/src/compat.ts

This file was deleted.

31 changes: 12 additions & 19 deletions packages/driver/src/datatypes/datetime.ts
Expand Up @@ -16,8 +16,6 @@
* limitations under the License.
*/

import * as bi from "../primitives/bigint";

import {
daysInMonth,
ymd2ord,
Expand Down Expand Up @@ -388,24 +386,24 @@ export class Duration {
toString(): string {
let dateParts = "";
if (this.years) {
dateParts += bi.make(Math.abs(this.years)) + "Y";
dateParts += BigInt(Math.abs(this.years)) + "Y";
}
if (this.months) {
dateParts += bi.make(Math.abs(this.months)) + "M";
dateParts += BigInt(Math.abs(this.months)) + "M";
}
if (this.weeks) {
dateParts += bi.make(Math.abs(this.weeks)) + "W";
dateParts += BigInt(Math.abs(this.weeks)) + "W";
}
if (this.days) {
dateParts += bi.make(Math.abs(this.days)) + "D";
dateParts += BigInt(Math.abs(this.days)) + "D";
}

let timeParts = "";
if (this.hours) {
timeParts += bi.make(Math.abs(this.hours)) + "H";
timeParts += BigInt(Math.abs(this.hours)) + "H";
}
if (this.minutes) {
timeParts += bi.make(Math.abs(this.minutes)) + "M";
timeParts += BigInt(Math.abs(this.minutes)) + "M";
}
if (
(!dateParts && !timeParts) ||
Expand All @@ -414,17 +412,12 @@ export class Duration {
this.microseconds ||
this.nanoseconds
) {
const totalNanoseconds = bi
.add(
bi.add(
bi.add(
bi.mul(bi.make(Math.abs(this.seconds)), bi.make(1e9)),
bi.mul(bi.make(Math.abs(this.milliseconds)), bi.make(1e6))
),
bi.mul(bi.make(Math.abs(this.microseconds)), bi.make(1e3))
),
bi.make(Math.abs(this.nanoseconds))
)
const totalNanoseconds = (
BigInt(Math.abs(this.seconds)) * BigInt(1e9) +
BigInt(Math.abs(this.milliseconds)) * BigInt(1e6) +
BigInt(Math.abs(this.microseconds)) * BigInt(1e3) +
BigInt(Math.abs(this.nanoseconds))
)
.toString()
.padStart(10, "0");

Expand Down
40 changes: 19 additions & 21 deletions packages/driver/src/datatypes/memory.ts
Expand Up @@ -16,27 +16,25 @@
* limitations under the License.
*/

import * as bi from "../primitives/bigint";

const KiB = 1024;
const MiB = 1024 * KiB;
const GiB = 1024 * MiB;
const TiB = 1024 * GiB;
const PiB = 1024 * TiB;

export class ConfigMemory {
private readonly _bytes: bi.BigIntLike;
private readonly _bytes: bigint;

constructor(bytes: bi.BigIntLike) {
constructor(bytes: bigint) {
this._bytes = bytes;
}

get bytes(): number {
return Number(this._bytes);
}

get bytesBigInt(): BigInt {
return this._bytes as BigInt;
get bytesBigInt(): bigint {
return this._bytes;
}

get kibibytes(): number {
Expand All @@ -61,25 +59,25 @@ export class ConfigMemory {

toString(): string {
const bytes = this._bytes;
const bigPiB = bi.make(PiB);
if (bi.gte(bytes, bigPiB) && Number(bi.remainder(bytes, bigPiB)) === 0) {
return `${bi.div(bytes, bigPiB)}PiB`;
const bigPiB = BigInt(PiB);
if (bytes >= bigPiB && Number(bytes % bigPiB) === 0) {
return `${bytes / bigPiB}PiB`;
}
const bigTiB = bi.make(TiB);
if (bi.gte(bytes, bigTiB) && Number(bi.remainder(bytes, bigTiB)) === 0) {
return `${bi.div(bytes, bigTiB)}TiB`;
const bigTiB = BigInt(TiB);
if (bytes >= bigTiB && Number(bytes % bigTiB) === 0) {
return `${bytes / bigTiB}TiB`;
}
const bigGiB = bi.make(GiB);
if (bi.gte(bytes, bigGiB) && Number(bi.remainder(bytes, bigGiB)) === 0) {
return `${bi.div(bytes, bigGiB)}GiB`;
const bigGiB = BigInt(GiB);
if (bytes >= bigGiB && Number(bytes % bigGiB) === 0) {
return `${bytes / bigGiB}GiB`;
}
const bigMiB = bi.make(MiB);
if (bi.gte(bytes, bigMiB) && Number(bi.remainder(bytes, bigMiB)) === 0) {
return `${bi.div(bytes, bigMiB)}MiB`;
const bigMiB = BigInt(MiB);
if (bytes >= bigMiB && Number(bytes % bigMiB) === 0) {
return `${bytes / bigMiB}MiB`;
}
const bigKiB = bi.make(KiB);
if (bi.gte(bytes, bigKiB) && Number(bi.remainder(bytes, bigKiB)) === 0) {
return `${bi.div(bytes, bigKiB)}KiB`;
const bigKiB = BigInt(KiB);
if (bytes >= bigKiB && Number(bytes % bigKiB) === 0) {
return `${bytes / bigKiB}KiB`;
}
return `${bytes}B`;
}
Expand Down

0 comments on commit 5dd3fa9

Please sign in to comment.