Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve packing performance #27

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 68 additions & 125 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@

// The dictionary
var dictionary = {
strings : [],
integers : [],
floats : []
strings : {},
integers : {},
floats : {},
stringsLen: 0,
integersLen: 0,
floatsLen: 0
};

verbose && console.log('Creating the AST');
Expand Down Expand Up @@ -110,59 +113,70 @@

// Case 4: The item is String
if (type === 'string') {

item = _encode(item);
// The index of that word in the dictionary
var index = _indexOf.call(dictionary.strings, item);

// If not, add to the dictionary and actualize the index
if (index == -1) {
dictionary.strings.push(_encode(item));
index = dictionary.strings.length - 1;
if (item in dictionary.strings) {
// Return the token
return {
type : 'strings',
index : dictionary.strings[item]
}
} else {
// If not, add to the dictionary and actualize the index
var index = dictionary.stringsLen;
dictionary.strings[item] = index;
dictionary.stringsLen += 1;
// Return the token
return {
type : 'strings',
index : index
}
}

// Return the token
return {
type : 'strings',
index : index
};
}

// Case 5: The item is integer
if (type === 'number' && item % 1 === 0) {

item = _base10To36(item);
// The index of that number in the dictionary
var index = _indexOf.call(dictionary.integers, item);

// If not, add to the dictionary and actualize the index
if (index == -1) {
dictionary.integers.push(_base10To36(item));
index = dictionary.integers.length - 1;
if(item in dictionary.integers) {
// Return the token
return {
type : 'integers',
index : dictionary.integers[item]
};
} else {
// If not, add to the dictionary and actualize the index
var index = dictionary.integersLen;
dictionary.integers[item] = index;
dictionary.integersLen += 1;
// Return the token
return {
type : 'integers',
index : index
};
}

// Return the token
return {
type : 'integers',
index : index
};
}

// Case 6: The item is float
if (type === 'number') {
// The index of that number in the dictionary
var index = _indexOf.call(dictionary.floats, item);

// If not, add to the dictionary and actualize the index
if (index == -1) {
// Float not use base 36
dictionary.floats.push(item);
index = dictionary.floats.length - 1;
if(item in dictionary.floats) {
// Return the token
return {
type : 'floats',
index : dictionary.floats[item]
};
} else {
// If not, add to the dictionary and actualize the index
var index = dictionary.floatsLen;
dictionary.floats[item] = index;
dictionary.floatsLen += 1;
// Return the token
return {
type : 'floats',
index : index
};
}

// Return the token
return {
type : 'floats',
index : index
};
}

// Case 7: The item is boolean
Expand All @@ -179,16 +193,16 @@
})(json);

// A set of shorthands proxies for the length of the dictionaries
var stringLength = dictionary.strings.length;
var integerLength = dictionary.integers.length;
var floatLength = dictionary.floats.length;
var stringLength = dictionary.stringsLen;
var integerLength = dictionary.integersLen;
var floatLength = dictionary.floatsLen;

verbose && console.log('Parsing the dictionary');

// Create a raw dictionary
var packed = dictionary.strings.join('|');
packed += '^' + dictionary.integers.join('|');
packed += '^' + dictionary.floats.join('|');
var packed = _getSortedKeys(dictionary.strings, dictionary.stringsLen).join('|');
packed += '^' + _getSortedKeys(dictionary.integers, dictionary.integersLen).join('|');
packed += '^' + _getSortedKeys(dictionary.floats, dictionary.floatsLen).join('|');

verbose && console.log('Parsing the structure');

Expand Down Expand Up @@ -442,75 +456,14 @@
})();

}
/**
* Get the index value of the dictionary
* @param {Object} dictionary a object that have two array attributes: 'string' and 'number'
* @param {Object} data
*/
var _indexOfDictionary = function(dictionary, value) {

// The type of the value
var type = typeof value;

// If is boolean, return a boolean token
if (type === 'boolean')
return value ? TOKEN_TRUE : TOKEN_FALSE;

// If is null, return a... yes! the null token
if (value === null)
return TOKEN_NULL;

//add undefined
if (typeof value === 'undefined')
return TOKEN_UNDEFINED;


if (value === '') {
return TOKEN_EMPTY_STRING;
var _getSortedKeys = function(dict, len) {
var arr = new Array(len);
for (var key in dict) {
arr[dict[key]] = key;
}

if (type === 'string') {
value = _encode(value);
var index = _indexOf.call(dictionary.strings, value);
if (index === -1) {
dictionary.strings.push(value);
index = dictionary.strings.length - 1;
}
}

// If has an invalid JSON type (example a function)
if (type !== 'string' && type !== 'number') {
throw new Error('The type is not a JSON type');
};

if (type === 'string') {// string
value = _encode(value);
} else if (value % 1 === 0) {// integer
value = _base10To36(value);
} else {// float

}

// If is number, "serialize" the value
value = type === 'number' ? _base10To36(value) : _encode(value);

// Retrieve the index of that value in the dictionary
var index = _indexOf.call(dictionary[type], value);

// If that value is not in the dictionary
if (index === -1) {
// Push the value
dictionary[type].push(value);
// And return their index
index = dictionary[type].length - 1;
}

// If the type is a number, then add the '+' prefix character
// to differentiate that they is a number index. If not, then
// just return a 36-based representation of the index
return type === 'number' ? '+' + index : index;

};
return arr;
}

var _encode = function(str) {
if ( typeof str !== 'string')
Expand Down Expand Up @@ -550,16 +503,6 @@
return parseInt(number, 36);
};

var _indexOf = Array.prototype.indexOf ||
function(obj, start) {
for (var i = (start || 0), j = this.length; i < j; i++) {
if (this[i] === obj) {
return i;
}
}
return -1;
};

return {
JSON : JSON,
pack : pack,
Expand Down
4 changes: 2 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ describe('jsonpack', function() {
attr2 : plainObject,
attr3 : [plainObject, plainObject]
},
deepObjectPacked = "attr1|string|hello|integer|float|true|false|null|attr2|attr3^1J9|1J9|1J9|1J9^1.2^$0|$1|2|3|A|4|E|5|-1|6|-2|7|-3]|8|$1|2|3|B|4|E|5|-1|6|-2|7|-3]|9|@$1|2|3|C|4|E|5|-1|6|-2|7|-3]|$1|2|3|D|4|E|5|-1|6|-2|7|-3]]]";
deepObjectPacked = "attr1|string|hello|integer|float|true|false|null|attr2|attr3^1J9^1.2^$0|$1|2|3|A|4|B|5|-1|6|-2|7|-3]|8|$1|2|3|A|4|B|5|-1|6|-2|7|-3]|9|@$1|2|3|A|4|B|5|-1|6|-2|7|-3]|$1|2|3|A|4|B|5|-1|6|-2|7|-3]]]";

var arrayObject = [
plainObject,
deepObject
],
arrayObjectPacked = "string|hello|integer|float|true|false|null|attr1|attr2|attr3^1J9|1J9|1J9|1J9|1J9^1.2^@$0|1|2|A|3|F|4|-1|5|-2|6|-3]|$7|$0|1|2|B|3|F|4|-1|5|-2|6|-3]|8|$0|1|2|C|3|F|4|-1|5|-2|6|-3]|9|@$0|1|2|D|3|F|4|-1|5|-2|6|-3]|$0|1|2|E|3|F|4|-1|5|-2|6|-3]]]]";
arrayObjectPacked = "string|hello|integer|float|true|false|null|attr1|attr2|attr3^1J9^1.2^@$0|1|2|A|3|B|4|-1|5|-2|6|-3]|$7|$0|1|2|A|3|B|4|-1|5|-2|6|-3]|8|$0|1|2|A|3|B|4|-1|5|-2|6|-3]|9|@$0|1|2|A|3|B|4|-1|5|-2|6|-3]|$0|1|2|A|3|B|4|-1|5|-2|6|-3]]]]";

describe('elemental', function() {

Expand Down