Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 624d72f

Browse files
authored
Merge pull request #1489 from myfreeer/col-cache-performance
col-cache: optimize for performance
2 parents a682091 + e8731f8 commit 624d72f

File tree

1 file changed

+51
-22
lines changed

1 file changed

+51
-22
lines changed

lib/utils/col-cache.js

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const addressRegex = /^[A-Z]+\d+$/;
12
// =========================================================================
23
// Column Letter to Number conversion
34
const colCache = {
@@ -29,6 +30,7 @@ const colCache = {
2930
'Y',
3031
'Z',
3132
],
33+
_l2nFill: 0,
3234
_l2n: {},
3335
_n2l: [],
3436
_level(n) {
@@ -48,18 +50,20 @@ const colCache = {
4850
let l3;
4951
let n = 1;
5052
if (level >= 4) {
51-
throw new Error(`Out of bounds. Excel supports columns from 1 to 16384`);
53+
throw new Error('Out of bounds. Excel supports columns from 1 to 16384');
5254
}
53-
if (level >= 1) {
55+
if (this._l2nFill < 1 && level >= 1) {
5456
while (n <= 26) {
5557
c = this._dictionary[n - 1];
5658
this._n2l[n] = c;
5759
this._l2n[c] = n;
5860
n++;
5961
}
62+
this._l2nFill = 1;
6063
}
61-
if (level >= 2) {
62-
while (n <= 26 + 26 * 26) {
64+
if (this._l2nFill < 2 && level >= 2) {
65+
n = 27;
66+
while (n <= 26 + (26 * 26)) {
6367
v = n - (26 + 1);
6468
l1 = v % 26;
6569
l2 = Math.floor(v / 26);
@@ -68,10 +72,12 @@ const colCache = {
6872
this._l2n[c] = n;
6973
n++;
7074
}
75+
this._l2nFill = 2;
7176
}
72-
if (level >= 3) {
77+
if (this._l2nFill < 3 && level >= 3) {
78+
n = 26 + (26 * 26) + 1;
7379
while (n <= 16384) {
74-
v = n - (26 * 26 + 26 + 1);
80+
v = n - ((26 * 26) + 26 + 1);
7581
l1 = v % 26;
7682
l2 = Math.floor(v / 26) % 26;
7783
l3 = Math.floor(v / (26 * 26));
@@ -80,6 +86,7 @@ const colCache = {
8086
this._l2n[c] = n;
8187
n++;
8288
}
89+
this._l2nFill = 3;
8390
}
8491
},
8592
l2n(l) {
@@ -107,41 +114,63 @@ const colCache = {
107114

108115
// check if value looks like an address
109116
validateAddress(value) {
110-
if (!value.match(/^[A-Z]+\d+$/)) {
117+
if (!addressRegex.test(value)) {
111118
throw new Error(`Invalid Address: ${value}`);
112119
}
113120
return true;
114121
},
115122

116123
// convert address string into structure
117124
decodeAddress(value) {
118-
const addr = this._hash[value];
125+
const addr = value.length < 5 && this._hash[value];
119126
if (addr) {
120127
return addr;
121128
}
122-
const matchCol = value.match(/[A-Z]+/);
123-
let col;
124-
let colNumber;
125-
if (matchCol) {
126-
col = matchCol[0];
127-
colNumber = this.l2n(col);
129+
let hasCol = false;
130+
let col = '';
131+
let colNumber = 0;
132+
let hasRow = false;
133+
let row = '';
134+
let rowNumber = 0;
135+
for (let i = 0, char; i < value.length; i++) {
136+
char = value.charCodeAt(i);
137+
// col should before row
138+
if (!hasRow && char >= 65 && char <= 90) {
139+
// 65 = 'A'.charCodeAt(0)
140+
// 90 = 'Z'.charCodeAt(0)
141+
hasCol = true;
142+
col += value[i];
143+
// colNumber starts from 1
144+
colNumber = (colNumber * 26) + char - 64;
145+
} else if (char >= 48 && char <= 57) {
146+
// 48 = '0'.charCodeAt(0)
147+
// 57 = '9'.charCodeAt(0)
148+
hasRow = true;
149+
row += value[i];
150+
// rowNumber starts from 0
151+
rowNumber = (rowNumber * 10) + char - 48;
152+
} else if (hasRow && hasCol && char !== 36) {
153+
// 36 = '$'.charCodeAt(0)
154+
break;
155+
}
156+
}
157+
if (!hasCol) {
158+
colNumber = undefined;
159+
} else if (colNumber > 16384) {
160+
throw new Error(`Out of bounds. Invalid column letter: ${col}`);
128161
}
129-
const matchRow = value.match(/\d+/);
130-
let row;
131-
let rowNumber;
132-
if (matchRow) {
133-
row = matchRow[0];
134-
rowNumber = parseInt(row, 10);
162+
if (!hasRow) {
163+
rowNumber = undefined;
135164
}
136165

137166
// in case $row$col
138-
value = (col || '') + (row || '');
167+
value = col + row;
139168

140169
const address = {
141170
address: value,
142171
col: colNumber,
143172
row: rowNumber,
144-
$col$row: `$${col || ''}$${row || ''}`,
173+
$col$row: `$${col}$${row}`,
145174
};
146175

147176
// mem fix - cache only the tl 100x100 square

0 commit comments

Comments
 (0)