Skip to content

Commit

Permalink
HighloadQueryId.js
Browse files Browse the repository at this point in the history
  • Loading branch information
rise1507 committed Mar 28, 2024
1 parent c2ba773 commit 424edad
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
105 changes: 105 additions & 0 deletions src/contract/highloadWallet/HighloadQueryId.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
const BIT_NUMBER_SIZE = 10n; // 10 bit
const SHIFT_SIZE = 13n; // 13 bit
const MAX_BIT_NUMBER = 1022n;
const MAX_SHIFT = 8191n; // 2^13 = 8192

class HighloadQueryId {
constructor() {
/**
* @private
* @type {bigint} [0 .. 8191]
*/
this.shift = 0n;
/**
* @private
* @type {bigint} [0 .. 1022]
*/
this.bitnumber = 0n;
}

/**
* @param shift {bigint}
* @param bitnumber {bigint}
* @return {HighloadQueryId}
*/
static fromShiftAndBitNumber(shift, bitnumber) {
const q = new HighloadQueryId();
q.shift = shift;
if (q.shift < 0) throw new Error('invalid shift');
if (q.shift > MAX_SHIFT) throw new Error('invalid shift');
q.bitnumber = bitnumber;
if (q.bitnumber < 0) throw new Error('invalid bitnumber');
if (q.bitnumber > MAX_BIT_NUMBER) throw new Error('invalid bitnumber');
return q;
}

increase() {
this.bitnumber += 1n;

if (this.shift === MAX_SHIFT && this.bitnumber > (MAX_BIT_NUMBER - 1n)) {
throw new Error('Overload'); // NOTE: we left one queryId for emergency withdraw
}

if (this.bitnumber > MAX_BIT_NUMBER) {
this.bitnumber = 0n;
this.shift += 1n;
if (this.shift > MAX_SHIFT) {
throw new Error('Overload')
}
}
}

isEnd() {
return this.bitnumber >= (MAX_BIT_NUMBER - 1n) && this.shift === MAX_SHIFT; // NOTE: we left one queryId for emergency withdraw
}

/**
* @return {bigint}
*/
getShift() {
return this.shift;
}

/**
* @return {bigint}
*/
getBitNumber() {
return this.bitnumber;
}

/**
* @return {bigint}
*/
getQueryId() {
return (this.shift << BIT_NUMBER_SIZE) + this.bitnumber;
}

/**
* @param queryId {bigint}
* @return {HighloadQueryId}
*/
static fromQueryId(queryId) {
const shift = queryId >> BIT_NUMBER_SIZE;
const bitnumber = queryId & 1023n;
return this.fromShiftAndBitNumber(shift, bitnumber);
}

/**
* @param i {bigint}
* @return {HighloadQueryId}
*/
static fromSeqno(i) {
const shift = i / 1023n;
const bitnumber = i % 1023n;
return this.fromShiftAndBitNumber(shift, bitnumber);
}

/**
* @return {bigint} [0 .. 8380415]
*/
toSeqno() {
return this.bitnumber + this.shift * 1023n;
}
}

module.exports = {HighloadQueryId};
41 changes: 41 additions & 0 deletions src/test-highload-query-id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const {HighloadQueryId} = require("./contract/highloadWallet/HighloadQueryId");

if (HighloadQueryId.fromSeqno(0n).toSeqno() !== 0n) throw new Error();

const i = HighloadQueryId.fromSeqno(1022n);
if (i.toSeqno() !== 1022n) throw new Error();
const i2 = HighloadQueryId.fromSeqno(1023n);
if (i2.toSeqno() !== 1023n) throw new Error();
const i3 = HighloadQueryId.fromSeqno(1024n);
if (i3.toSeqno() !== 1024n) throw new Error();
const i4 = HighloadQueryId.fromSeqno(8380415n);
if (i4.toSeqno() !== 8380415n) throw new Error();


const queryId = new HighloadQueryId();
console.log(queryId.getQueryId(), queryId.isEnd());

const MAX = (2n ** 13n) * 1023n - 2n;
for (let i = 0; i < MAX; i++) {
queryId.increase();

const q = queryId.getQueryId();
const q2 = HighloadQueryId.fromQueryId(q);

if (queryId.getShift() !== q2.getShift()) throw new Error()
if (queryId.getBitNumber() !== q2.getBitNumber()) throw new Error()
if (q2.getQueryId() !== q) throw new Error();

const q3 = HighloadQueryId.fromShiftAndBitNumber(queryId.getShift(), queryId.getBitNumber());
if (queryId.getShift() !== q3.getShift()) throw new Error()
if (queryId.getBitNumber() !== q3.getBitNumber()) throw new Error()
if (q3.getQueryId() !== q) throw new Error();

if (queryId.isEnd()) {
console.log('END')
}
}
console.log(queryId.shift);
console.log(queryId.bitnumber);

console.log(queryId.getQueryId(), queryId.isEnd());

0 comments on commit 424edad

Please sign in to comment.