src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts/PieceTreeBase/createNewPieces
class PieceTreeBase:	private createNewPieces(text: string): Piece[] {
		if (text.length > AverageBufferSize) {
			// the content is large, operations like substring, charCode becomes slow
			// so here we split it into smaller chunks, just like what we did for CR/LF normalization
			const newPieces: Piece[] = [];
			while (text.length > AverageBufferSize) {
				const lastChar = text.charCodeAt(AverageBufferSize - 1);
				let splitText;
				if (lastChar === CharCode.CarriageReturn || (lastChar >= 0xD800 && lastChar <= 0xDBFF)) {
					// last character is \r or a high surrogate => keep it back
					splitText = text.substring(0, AverageBufferSize - 1);
					text = text.substring(AverageBufferSize - 1);
				} else {
					splitText = text.substring(0, AverageBufferSize);
					text = text.substring(AverageBufferSize);
				}

				const lineStarts = createLineStartsFast(splitText);
				newPieces.push(new Piece(
					this._buffers.length, /* buffer index */
					{ line: 0, column: 0 },
					{ line: lineStarts.length - 1, column: splitText.length - lineStarts[lineStarts.length - 1] },
					lineStarts.length - 1,
					splitText.length
				));
				this._buffers.push(new StringBuffer(splitText, lineStarts));
			}

			const lineStarts = createLineStartsFast(text);
			newPieces.push(new Piece(
				this._buffers.length, /* buffer index */
				{ line: 0, column: 0 },
				{ line: lineStarts.length - 1, column: text.length - lineStarts[lineStarts.length - 1] },
				lineStarts.length - 1,
				text.length
			));
			this._buffers.push(new StringBuffer(text, lineStarts));

			return newPieces;
		}

		let startOffset = this._buffers[0].buffer.length;
		const lineStarts = createLineStartsFast(text, false);

		let start = this._lastChangeBufferPos;
		if (this._buffers[0].lineStarts[this._buffers[0].lineStarts.length - 1] === startOffset
			&& startOffset !== 0
			&& this.startWithLF(text)
			&& this.endWithCR(this._buffers[0].buffer) // todo, we can check this._lastChangeBufferPos's column as it's the last one
		) {
			this._lastChangeBufferPos = { line: this._lastChangeBufferPos.line, column: this._lastChangeBufferPos.column + 1 };
			start = this._lastChangeBufferPos;

			for (let i = 0; i < lineStarts.length; i++) {
				lineStarts[i] += startOffset + 1;
			}

			this._buffers[0].lineStarts = (<number[]>this._buffers[0].lineStarts).concat(<number[]>lineStarts.slice(1));
			this._buffers[0].buffer += '_' + text;
			startOffset += 1;
		} else {
			if (startOffset !== 0) {
				for (let i = 0; i < lineStarts.length; i++) {
					lineStarts[i] += startOffset;
				}
			}
			this._buffers[0].lineStarts = (<number[]>this._buffers[0].lineStarts).concat(<number[]>lineStarts.slice(1));
			this._buffers[0].buffer += text;
		}

		const endOffset = this._buffers[0].buffer.length;
		const endIndex = this._buffers[0].lineStarts.length - 1;
		const endColumn = endOffset - this._buffers[0].lineStarts[endIndex];
		const endPos = { line: endIndex, column: endColumn };
		const newPiece = new Piece(
			0, /** todo@peng */
			start,
			endPos,
			this.getLineFeedCnt(0, start, endPos),
			endOffset - startOffset
		);
		this._lastChangeBufferPos = endPos;
		return [newPiece];
	}