From 44c9c29b72b8e6893e3ea8daf5ae7e8eef4213a3 Mon Sep 17 00:00:00 2001
From: swvitaliy <sw.vitaliy@gmail.com>
Date: Thu, 28 Jun 2018 16:35:26 +0300
Subject: [PATCH] Add property firstSlotStartMinutes into
 calculateWorkloadWeights response

---
 dist/cjs/utils.js  | 10 +++++++++-
 dist/cjs/vector.js |  2 +-
 package.json       |  2 +-
 src/utils.js       | 10 +++++++++-
 src/vector.js      |  2 +-
 test/vector.js     | 50 +++++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/dist/cjs/utils.js b/dist/cjs/utils.js
index a9d42b5..c7b714a 100644
--- a/dist/cjs/utils.js
+++ b/dist/cjs/utils.js
@@ -95,10 +95,18 @@ function calculateWorkloadWeights(slots, vectorSlotSize) {
         bs = _vector.busyBitSets[vectorSlotSize];
       }
       if (!ret[r.resourceId]) {
+        let minutes;
+        let p = { i: 0, b: 0 };
+        if (_find1(p, bs) === -1) {
+          minutes = 0;
+        } else {
+          minutes = (p.i * INT32_SIZE + p.b + 1) * vectorSlotSize;
+        }
         ret[r.resourceId] = {
           resourceId: r.resourceId,
           weight: 0,
-          firstSlotDate: day.date
+          firstSlotDate: day.date,
+          firstSlotStartMinutes: minutes
         };
       }
       ret[r.resourceId].weight = ret[r.resourceId].weight + bs.reduce(function (ret, bsi) {
diff --git a/dist/cjs/vector.js b/dist/cjs/vector.js
index 6f96f27..53a216e 100644
--- a/dist/cjs/vector.js
+++ b/dist/cjs/vector.js
@@ -52,7 +52,7 @@ function bitsetStrToInt32Array(str, vectorSlotSize) {
     // i  - char index: from numberOfTimeUnits - 1 to 0
     // bi - byte index: from 0 to 8
     bi = numberOfTimeUnits - 1 - i >> 5;
-    bs[bi] = bs[bi] << 1 | str[i] === "1";
+    bs[bi] = (bs[bi] << 1 | str[i] === "1") >>> 0;
   }
   return bs;
 }
diff --git a/package.json b/package.json
index 5b8179b..352819e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "crac-utils",
-  "version": "1.3.6",
+  "version": "1.3.7",
   "description": "The GBooking crac-utils library",
   "main": "dist/cjs/index.js",
   "scripts": {
diff --git a/src/utils.js b/src/utils.js
index f6dfb57..a01f50a 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -80,10 +80,18 @@ export function calculateWorkloadWeights(slots, vectorSlotSize) {
         bs = busyBitSets[vectorSlotSize];
       }
       if (!ret[r.resourceId]) {
+        let minutes;
+        let p = {i: 0, b: 0};
+        if (_find1(p, bs) === -1) {
+          minutes = 0;
+        } else {
+          minutes = (p.i * INT32_SIZE + p.b + 1) * vectorSlotSize;
+        }
         ret[r.resourceId] = {
           resourceId: r.resourceId,
           weight: 0,
-          firstSlotDate: day.date
+          firstSlotDate: day.date,
+          firstSlotStartMinutes: minutes
         };
       }
       ret[r.resourceId].weight = ret[r.resourceId].weight + bs.reduce(function(ret, bsi) {
diff --git a/src/vector.js b/src/vector.js
index d688b56..ff9029d 100644
--- a/src/vector.js
+++ b/src/vector.js
@@ -44,7 +44,7 @@ export function bitsetStrToInt32Array(str, vectorSlotSize) {
     // i  - char index: from numberOfTimeUnits - 1 to 0
     // bi - byte index: from 0 to 8
     bi = (numberOfTimeUnits - 1 - i) >> 5;
-    bs[bi] = bs[bi] << 1 | (str[i] === "1");
+    bs[bi] = (bs[bi] << 1 | (str[i] === "1")) >>> 0;
   }
   return bs;
 }
diff --git a/test/vector.js b/test/vector.js
index 2f41389..8a9de2f 100644
--- a/test/vector.js
+++ b/test/vector.js
@@ -41,7 +41,7 @@ describe('vector', function() {
     it('"1000..." string should generate 1 bit bitset', function() {
       var s = stringCracVector("1" + '0'.repeat(31));
       var bs = vector.bitsetStrToInt32Array(s);
-      (bs[0]).should.be.equal(1<<31);
+      (bs[0]).should.be.equal((1<<31) >>> 0);
     });
     it('3rd bit string should generate 3rd bit bitset', function() {
       var s = stringCracVector('0'.repeat(3) + "1");
@@ -175,5 +175,53 @@ describe('vector', function() {
       }]);
       _.find(weights, {resourceId: 'a'}).firstSlotDate.should.be.equal('2017-09-03 07:19:32.726Z');
     });
+    it('zero vector should return 0 startMinutes', function() {
+      var slotSize = 5;
+      var weights = utils.calculateWorkloadWeights([{
+        date: "2018-06-28T00:00:00Z",
+        resources:[{
+          resourceId: 'a',
+          bitset: stringCracVector('0'.repeat(288), slotSize)
+        }]
+      },], slotSize);
+      _.find(weights, {resourceId: 'a'}).firstSlotStartMinutes
+        .should.be.equal(0);
+    });
+    it('vector with start 1 bit should return 5 startMinutes', function() {
+      var slotSize = 5;
+      var weights = utils.calculateWorkloadWeights([{
+        date: "2018-06-28T00:00:00Z",
+        resources:[{
+          resourceId: 'a',
+          bitset: stringCracVector('1' + '0'.repeat(287), slotSize)
+        }]
+      },], slotSize);
+      _.find(weights, {resourceId: 'a'}).firstSlotStartMinutes
+        .should.be.equal(5);
+    });
+    it('vector with last 1 bit should return (numOfBits * slotSize) startMinutes', function() {
+      var slotSize = 5;
+      var weights = utils.calculateWorkloadWeights([{
+        date: "2018-06-28T00:00:00Z",
+        resources:[{
+          resourceId: 'a',
+          bitset: stringCracVector('0'.repeat(287) + '1', slotSize)
+        }]
+      },], slotSize);
+      _.find(weights, {resourceId: 'a'}).firstSlotStartMinutes
+        .should.be.equal(1440);
+    });
+    it('vector with 7th 1 bit should return 7 * startMinutes', function() {
+      var slotSize = 5;
+      var weights = utils.calculateWorkloadWeights([{
+        date: "2018-06-28T00:00:00Z",
+        resources:[{
+          resourceId: 'a',
+          bitset: stringCracVector('0'.repeat(6) + '1' + '0'.repeat(281), slotSize)
+        }]
+      },], slotSize);
+      _.find(weights, {resourceId: 'a'}).firstSlotStartMinutes
+        .should.be.equal(7 * slotSize);
+    });
   })
 });
\ No newline at end of file
-- 
GitLab