Filesystem: Work on entire buffer when writing to file

The Uint8Array that stores the file data is usually larger than the file
size itself, to improve the amortized complexity of resizing the array.

When we previously switched over to using FileStorages, the method
fs#Write() was modified to retrieve only the subarray of the Uint8Array
that contains the file (i.e. excluding the unused padding at the end),
so appending to a file always tries to resize the array even though the
ArrayBuffer that backs it has enough space for the new data.
This commit is contained in:
Ernest Wong 2018-12-16 22:37:11 +13:00 committed by Fabian
parent dbfa0edc3c
commit 3dde97f14a

View file

@ -846,12 +846,12 @@ FS.prototype.Write = async function(id, offset, count, buffer) { // jshint ignor
}
inode.dirty = true;
var data = await this.get_data(id, 0, inode.size); // jshint ignore:line
var data = await this.get_buffer(id); // jshint ignore:line
if (!data || data.length < (offset+count)) {
await this.ChangeSize(id, Math.floor(((offset+count)*3)/2)); // jshint ignore:line
inode.size = offset + count;
data = await this.get_data(id, 0, inode.size); // jshint ignore:line
data = await this.get_buffer(id); // jshint ignore:line
} else
if (inode.size < (offset+count)) {
inode.size = offset + count;
@ -1061,6 +1061,33 @@ FS.prototype.DeleteData = async function(idx) // jshint ignore:line
delete this.inodedata[idx];
}; // jshint ignore:line
/**
* @private
* @param {number} idx
* @return {!Promise<Uint8Array>} The buffer that contains the file contents, which may be larger
* than the data itself. To ensure that any modifications done to this buffer is reflected
* to the file, call set_data with the modified buffer.
*/
FS.prototype.get_buffer = async function(idx) // jshint ignore:line
{
const inode = this.inodes[idx];
dbg_assert(inode, `Filesystem get_buffer: idx ${idx} does not point to an inode`);
if(this.inodedata[idx])
{
return this.inodedata[idx];
}
else if(inode.status === STATUS_ON_STORAGE)
{
dbg_assert(inode.sha256sum, "Filesystem get_data: found inode on server without sha256sum");
return await this.storage.read(inode.sha256sum, 0, inode.size); // jshint ignore:line
}
else
{
return null;
}
}; // jshint ignore:line
/**
* @private
* @param {number} idx