Skip to content

Commit ce9f108

Browse files
committed
First release
1 parent 331bd23 commit ce9f108

File tree

5 files changed

+215
-1
lines changed

5 files changed

+215
-1
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
language: node_js
2+
node_js:
3+
- "stable"
4+
- "0.12"
5+
- "0.11"
6+
- "iojs"
7+
script: npm test

FastIntegerCompression.js

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* FastIntegerCompression.js : a fast integer compression library in JavaScript.
3+
* (c) the authors
4+
* Licensed under the Apache License, Version 2.0.
5+
*
6+
*FastIntegerCompression
7+
* Simple usage :
8+
* // var FastIntegerCompression = require("fastintcompression");// if you use node
9+
* var b = new FastBitSet();// initially empty
10+
* b.add(1);// add the value "1"
11+
* b.has(1); // check that the value is present! (will return true)
12+
* b.add(2);
13+
* console.log(""+b);// should display {1,2}
14+
* b.add(10);
15+
* b.array(); // would return [1,2,10]
16+
*
17+
* var c = new FastBitSet([1,2,3,10]); // create bitset initialized with values 1,2,3,10
18+
* c.difference(b); // from c, remove elements that are in b
19+
* var su = c.union_size(b);// compute the size of the union (bitsets are unchanged)
20+
* c.union(b); // c will contain all elements that are in c and b
21+
* var s1 = c.intersection_size(b);// compute the size of the intersection (bitsets are unchanged)
22+
* c.intersection(b); // c will only contain elements that are in both c and b
23+
* c = b.clone(); // create a (deep) copy of b and assign it to c.
24+
* c.equals(b); // check whether c and b are equal
25+
*
26+
* See README.md file for a more complete description.
27+
*
28+
* You can install the library under node with the command line
29+
* npm install fastbitset
30+
*/
31+
'use strict';
32+
33+
34+
// you can provide an iterable
35+
function FastIntegerCompression() {
36+
}
37+
38+
function bytelog(val) {
39+
if (val < (1 << 7)) {
40+
return 1;
41+
} else if (val < (1 << 14)) {
42+
return 2;
43+
} else if (val < (1 << 21)) {
44+
return 3;
45+
} else if (val < (1 << 28)) {
46+
return 4;
47+
}
48+
return 5;
49+
}
50+
51+
// compute how many bytes an array of integers would use once compressed
52+
FastIntegerCompression.computeCompressedSizeInBytes = function(input) {
53+
var c = input.length;
54+
var answer = 0;
55+
for(var i = 0; i < c; i++) {
56+
answer += bytelog(input[i]);
57+
}
58+
return answer;
59+
};
60+
61+
62+
// compress an array of integers, return a compressed buffer (as an ArrayBuffer)
63+
FastIntegerCompression.compress = function(input) {
64+
var c = input.length;
65+
var buf = new ArrayBuffer(FastIntegerCompression.computeCompressedSizeInBytes(input));
66+
var view = new Int8Array(buf);
67+
var pos = 0
68+
for(var i = 0; i < c; i++) {
69+
var val = input[i];
70+
if (val < (1 << 7)) {
71+
view[pos++] = val ;
72+
} else if (val < (1 << 14)) {
73+
view[pos++] = (val & 0x7F) | 0x80;
74+
view[pos++] = val >>> 7;
75+
} else if (val < (1 << 21)) {
76+
view[pos++] = (val & 0x7F) | 0x80;
77+
view[pos++] = ( (val >>> 7) & 0x7F ) | 0x80;
78+
view[pos++] = val >>> 14;
79+
} else if (val < (1 << 28)) {
80+
view[pos++] = (val & 0x7F ) | 0x80 ;
81+
view[pos++] = ( (val >>> 7) & 0x7F ) | 0x80;
82+
view[pos++] = ( (val >>> 14) & 0x7F ) | 0x80;
83+
view[pos++] = val >>> 21;
84+
} else {
85+
view[pos++] = ( val & 0x7F ) | 0x80;
86+
view[pos++] = ( (val >>> 7) & 0x7F ) | 0x80;
87+
view[pos++] = ( (val >>> 14) & 0x7F ) | 0x80;
88+
view[pos++] = ( (val >>> 21) & 0x7F ) | 0x80;
89+
view[pos++] = val >>> 28;
90+
}
91+
}
92+
return buf;
93+
};
94+
95+
// from a compressed array of integers stored ArrayBuffer, compute the number of compressed integers by scanning the input
96+
FastIntegerCompression.computeHowManyIntegers = function(input) {
97+
var view = new UInt8Array(input);
98+
var c = view.length;
99+
var count = 0;
100+
for(var i = 0; i < c; i++) {
101+
count += (input[i]>>>7);
102+
}
103+
return c - count;
104+
}
105+
106+
// uncompress an array of integer from an ArrayBuffer, return the array
107+
FastIntegerCompression.uncompress = function(input) {
108+
var array = new Array()
109+
var inbyte = new Int8Array(input);
110+
var end = inbyte.length;
111+
var pos = 0;
112+
while (end > pos) {
113+
var c = inbyte[pos++];
114+
var v = c & 0x7F;
115+
if (c >= 0) {
116+
array.push(v)
117+
continue;
118+
}
119+
c = inbyte[pos++];
120+
v |= (c & 0x7F) << 7;
121+
if (c >= 0) {
122+
array.push(v)
123+
continue;
124+
}
125+
c = inbyte[pos++];
126+
v |= (c & 0x7F) << 14;
127+
if (c >= 0) {
128+
array.push(v)
129+
continue;
130+
}
131+
c = inbyte[pos++];
132+
v |= (c & 0x7F) << 21;
133+
if (c >= 0) {
134+
array.push(v)
135+
continue;
136+
}
137+
c = inbyte[pos++];
138+
v |= c << 28;
139+
array.push(v)
140+
}
141+
return array;
142+
};
143+
144+
145+
146+
///////////////
147+
148+
module.exports = FastIntegerCompression;

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
# FastIntegerCompression
2-
Fast integer compression library in JavaScript
2+
This is an integer compression library in JavaScript, useful for work on indexes.
3+
4+
Status: highly experimental.

package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "fastintcompression",
3+
"description": "a fast integer compression library in JavaScript",
4+
"keywords": [
5+
"integers",
6+
"compression",
7+
"performance"
8+
],
9+
"version": "0.0.1",
10+
"repository": {
11+
"type": "git",
12+
"url": "git+https://github.com/lemire/FastIntegerCompression.js.git"
13+
},
14+
"main": "FastIntegerCompression.js",
15+
"scripts": {
16+
"test": "mocha unit/basictests.js"
17+
},
18+
"license": "Apache-2.0",
19+
"bugs": {
20+
"url": "https://github.com/lemire/FastIntegerCompression.js/issues"
21+
},
22+
"homepage": "https://github.com/lemire/FastIntegerCompression.js#readme",
23+
"dependencies": {
24+
"benchmark": "~1.0.0",
25+
"mocha": "^2.3.4"
26+
},
27+
"devDependencies": {
28+
"mocha": "^2.3.2"
29+
},
30+
"author": "Daniel Lemire <lemire@gmail.com> (http://lemire.me/en/)"
31+
}

unit/basictests.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* This script expects node.js and mocha */
2+
3+
'use strict';
4+
5+
describe('FastIntegerCompression', function() {
6+
var FastIntegerCompression = require('../FastIntegerCompression.js');
7+
8+
function arraysEquals(a, b) {
9+
var i = a.length;
10+
if (i != b.length) return false;
11+
while (i--) {
12+
if (a[i] !== b[i]) return false;
13+
}
14+
return true;
15+
};
16+
17+
it('Testing simple compression', function() {
18+
var array = [10,100000,65999,10,10,0,1,1,2000];
19+
var buf = FastIntegerCompression.compress(array);
20+
var back = FastIntegerCompression.uncompress(buf);
21+
if(!arraysEquals(array,back)) throw "bad";
22+
23+
});
24+
25+
26+
});

0 commit comments

Comments
 (0)