2013-01-31 01:49:25 +08:00
|
|
|
/*
|
|
|
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
|
|
Author Tobias Koppers @sokra
|
|
|
|
*/
|
2014-01-23 22:31:40 +08:00
|
|
|
function Chunk(name, module, loc) {
|
2013-01-31 01:49:25 +08:00
|
|
|
this.id = null;
|
2013-05-08 19:28:54 +08:00
|
|
|
this.ids = null;
|
2013-01-31 01:49:25 +08:00
|
|
|
this.name = name;
|
|
|
|
this.modules = [];
|
|
|
|
this.chunks = [];
|
|
|
|
this.parents = [];
|
|
|
|
this.blocks = [];
|
2014-01-23 22:31:40 +08:00
|
|
|
this.origins = [];
|
2013-05-08 19:28:54 +08:00
|
|
|
this.rendered = false;
|
2013-12-04 06:11:14 +08:00
|
|
|
this.entry = false;
|
|
|
|
this.initial = false;
|
2014-06-04 03:03:21 +08:00
|
|
|
if(module) {
|
|
|
|
this.origins.push({
|
|
|
|
module: module,
|
|
|
|
loc: loc,
|
|
|
|
name: name
|
|
|
|
});
|
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
}
|
|
|
|
module.exports = Chunk;
|
|
|
|
|
|
|
|
Chunk.prototype.addModule = function(module) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(this.modules.indexOf(module) >= 0) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
this.modules.push(module);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2014-06-25 00:53:32 +08:00
|
|
|
Chunk.prototype._removeAndDo = require("./removeAndDo");
|
2013-01-31 01:49:25 +08:00
|
|
|
|
2014-06-25 00:53:32 +08:00
|
|
|
Chunk.prototype.removeModule = function(module) {
|
|
|
|
this._removeAndDo("modules", module, "removeChunk");
|
2013-01-31 01:49:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
Chunk.prototype.removeChunk = function(chunk) {
|
2014-06-25 00:53:32 +08:00
|
|
|
this._removeAndDo("chunks", chunk, "removeParent");
|
2013-01-31 01:49:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
Chunk.prototype.removeParent = function(chunk) {
|
2014-06-25 00:53:32 +08:00
|
|
|
this._removeAndDo("parents", chunk, "removeChunk");
|
2013-01-31 01:49:25 +08:00
|
|
|
};
|
|
|
|
|
2014-06-25 00:53:32 +08:00
|
|
|
function createAdder(collection) {
|
|
|
|
return function(chunk) {
|
|
|
|
if(chunk === this) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(this[collection].indexOf(chunk) >= 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this[collection].push(chunk);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
Chunk.prototype.addChunk = createAdder("chunks");
|
|
|
|
|
|
|
|
Chunk.prototype.addParent = createAdder("parents");
|
|
|
|
|
2013-01-31 01:49:25 +08:00
|
|
|
Chunk.prototype.addBlock = function(block) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(this.blocks.indexOf(block) >= 0) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
this.blocks.push(block);
|
|
|
|
return true;
|
|
|
|
};
|
2014-01-24 20:32:58 +08:00
|
|
|
|
|
|
|
Chunk.prototype.addOrigin = function(module, loc) {
|
|
|
|
this.origins.push({module: module, loc: loc, name: this.name});
|
|
|
|
};
|
2013-01-31 01:49:25 +08:00
|
|
|
|
|
|
|
Chunk.prototype.remove = function(reason) {
|
|
|
|
// console.log("remove " + this.toString());
|
|
|
|
this.modules.slice().forEach(function(m) {
|
|
|
|
m.removeChunk(this);
|
|
|
|
}, this);
|
|
|
|
this.parents.forEach(function(c) {
|
|
|
|
var idx = c.chunks.indexOf(this);
|
2014-06-04 03:03:21 +08:00
|
|
|
if(idx >= 0) {
|
2013-01-31 01:49:25 +08:00
|
|
|
c.chunks.splice(idx, 1);
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
this.chunks.forEach(function(cc) {
|
|
|
|
cc.addParent(c);
|
|
|
|
});
|
|
|
|
}, this);
|
|
|
|
this.chunks.forEach(function(c) {
|
|
|
|
var idx = c.parents.indexOf(this);
|
2014-06-04 03:03:21 +08:00
|
|
|
if(idx >= 0) {
|
2013-01-31 01:49:25 +08:00
|
|
|
c.parents.splice(idx, 1);
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
this.parents.forEach(function(cc) {
|
|
|
|
cc.addChunk(c);
|
|
|
|
});
|
|
|
|
}, this);
|
|
|
|
this.blocks.forEach(function(b) {
|
|
|
|
b.chunk = null;
|
|
|
|
b.chunkReason = reason;
|
|
|
|
}, this);
|
|
|
|
};
|
|
|
|
|
|
|
|
Chunk.prototype.integrate = function(other, reason) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(!this.canBeIntegrated(other)) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-04 01:12:19 +08:00
|
|
|
|
2013-01-31 01:49:25 +08:00
|
|
|
var otherModules = other.modules.slice();
|
|
|
|
otherModules.forEach(function(m) {
|
|
|
|
m.removeChunk(other);
|
|
|
|
m.addChunk(this);
|
|
|
|
this.addModule(m);
|
|
|
|
}, this);
|
|
|
|
other.modules.length = 0;
|
2014-06-25 00:53:32 +08:00
|
|
|
function moveChunks(chunks, kind, onChunk) {
|
|
|
|
chunks.forEach(function(c) {
|
|
|
|
var idx = c[kind].indexOf(other);
|
|
|
|
if(idx >= 0) {
|
|
|
|
c[kind].splice(idx, 1);
|
|
|
|
}
|
|
|
|
onChunk(c);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
moveChunks(other.parents, "chunks", function(c) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(c !== this && this.addParent(c)) {
|
2013-01-31 01:49:25 +08:00
|
|
|
c.addChunk(this);
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2014-06-25 00:53:32 +08:00
|
|
|
}.bind(this));
|
2013-01-31 01:49:25 +08:00
|
|
|
other.parents.length = 0;
|
2014-06-25 00:53:32 +08:00
|
|
|
moveChunks(other.chunks, "parents", function(c) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(c !== this && this.addChunk(c)) {
|
2013-01-31 01:49:25 +08:00
|
|
|
c.addParent(this);
|
2014-06-25 00:53:32 +08:00
|
|
|
}
|
|
|
|
}.bind(this));
|
2013-01-31 01:49:25 +08:00
|
|
|
other.chunks.length = 0;
|
|
|
|
other.blocks.forEach(function(b) {
|
|
|
|
b.chunk = this;
|
|
|
|
b.chunkReason = reason;
|
|
|
|
this.addBlock(b);
|
|
|
|
}, this);
|
|
|
|
other.blocks.length = 0;
|
2014-01-23 22:31:40 +08:00
|
|
|
other.origins.forEach(function(origin) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(!origin.reasons) {
|
|
|
|
origin.reasons = [reason];
|
|
|
|
} else if(origin.reasons[0] !== reason) {
|
|
|
|
origin.reasons.unshift(reason);
|
|
|
|
}
|
2014-01-23 22:31:40 +08:00
|
|
|
this.origins.push(origin);
|
|
|
|
}, this);
|
2014-02-04 01:12:19 +08:00
|
|
|
return true;
|
2013-01-31 01:49:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
Chunk.prototype.isEmpty = function() {
|
2014-06-04 03:03:21 +08:00
|
|
|
return (this.modules.length === 0);
|
2013-01-31 01:49:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
Chunk.prototype.updateHash = function(hash) {
|
2013-05-08 19:28:54 +08:00
|
|
|
hash.update(this.id + " ");
|
|
|
|
hash.update(this.ids ? this.ids.join(",") : "");
|
|
|
|
hash.update(this.name + "");
|
2013-01-31 01:49:25 +08:00
|
|
|
this.modules.forEach(function(m) {
|
|
|
|
m.updateHash(hash);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-06-18 00:55:11 +08:00
|
|
|
Chunk.prototype.size = function(options) {
|
|
|
|
var CHUNK_OVERHEAD = options.chunkOverhead || 10000;
|
|
|
|
var ENTRY_CHUNK_MULTIPLICATOR = options.entryChunkMultiplicator || 10;
|
|
|
|
|
|
|
|
var modulesSize = this.modules.map(function(m) {
|
|
|
|
return m.size();
|
|
|
|
}).reduce(function(a, b) {
|
|
|
|
return a + b;
|
|
|
|
}, 0);
|
2013-12-04 06:11:14 +08:00
|
|
|
return modulesSize * (this.initial ? ENTRY_CHUNK_MULTIPLICATOR : 1) + CHUNK_OVERHEAD;
|
2013-06-18 00:55:11 +08:00
|
|
|
};
|
|
|
|
|
2014-02-04 01:12:19 +08:00
|
|
|
Chunk.prototype.canBeIntegrated = function(other) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(other.initial) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-04 01:12:19 +08:00
|
|
|
if(this.initial) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(other.parents.length !== 1 || other.parents[0] !== this) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-04 01:12:19 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2013-06-18 00:55:11 +08:00
|
|
|
Chunk.prototype.integratedSize = function(other, options) {
|
2014-02-04 01:12:19 +08:00
|
|
|
// Chunk if it's possible to integrate this chunks
|
2014-06-04 03:03:21 +08:00
|
|
|
if(!this.canBeIntegrated(other)) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-04 01:12:19 +08:00
|
|
|
|
2013-06-18 00:55:11 +08:00
|
|
|
var CHUNK_OVERHEAD = options.chunkOverhead || 10000;
|
|
|
|
var ENTRY_CHUNK_MULTIPLICATOR = options.entryChunkMultiplicator || 10;
|
|
|
|
|
|
|
|
var mergedModules = this.modules.slice();
|
|
|
|
other.modules.forEach(function(m) {
|
2014-06-04 03:03:21 +08:00
|
|
|
if(this.modules.indexOf(m) < 0) {
|
2013-06-18 00:55:11 +08:00
|
|
|
mergedModules.push(m);
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2013-06-18 00:55:11 +08:00
|
|
|
}, this);
|
|
|
|
|
|
|
|
var modulesSize = mergedModules.map(function(m) {
|
|
|
|
return m.size();
|
|
|
|
}).reduce(function(a, b) {
|
|
|
|
return a + b;
|
|
|
|
}, 0);
|
2013-12-04 06:11:14 +08:00
|
|
|
return modulesSize * (this.initial || other.initial ? ENTRY_CHUNK_MULTIPLICATOR : 1) + CHUNK_OVERHEAD;
|
2013-06-18 00:55:11 +08:00
|
|
|
};
|
|
|
|
|
2013-01-31 01:49:25 +08:00
|
|
|
Chunk.prototype.toString = function() {
|
|
|
|
return "Chunk[" + this.modules.join() + "]";
|
|
|
|
};
|