Optimistic mkdir & create (avoid locking if possible)

This commit is contained in:
Jiang Yio 2022-10-01 07:58:01 -04:00
parent 53812f7c85
commit f8a50c31b6

View File

@ -93,17 +93,17 @@ export function TplFS(client, parent, desc) {
} else throw new TplFSErrorInvalid('open', (this.path != '' ? this.path + '/' : '') + path.join('/'), 'Invalid path'); } else throw new TplFSErrorInvalid('open', (this.path != '' ? this.path + '/' : '') + path.join('/'), 'Invalid path');
}; };
this.mkdir = async (path, tries=5, delay=1000) => { this.mkdir = async (path, optimistic=true, tries=5, delay=1000) => {
if((typeof path === 'string') || (path instanceof String)) path = path.split('/'); if((typeof path === 'string') || (path instanceof String)) path = path.split('/');
var node = this; var node = this;
for(var i = 0; i < path.length; ++i) node = await node.raw_mkdir(path[i], tries, delay); for(var i = 0; i < path.length; ++i) node = await node.raw_mkdir(path[i], optimistic, tries, delay);
return node; return node;
}; };
this.create = async (path, data, mkdir=false, tries=5, delay=1000) => { this.create = async (path, data, optimistic=true, mkdir=false, tries=5, delay=1000) => {
if((typeof path === 'string') || (path instanceof String)) path = path.split('/'); if((typeof path === 'string') || (path instanceof String)) path = path.split('/');
if(path.length > 1) return await (mkdir ? await this.mkdir(path.slice(0, -1), tries, delay) : await this.open(path.slice(0, -1))).create(path.slice(-1), data, tries, delay); if(path.length > 1) return await (mkdir ? await this.mkdir(path.slice(0, -1), optimistic, tries, delay) : await this.open(path.slice(0, -1))).create(path.slice(-1), data, optimistic, mkdir, tries, delay);
else if(path.length == 1) return await this.raw_create(path[0], data, tries, delay); else if(path.length == 1) return await this.raw_create(path[0], data, optimistic, tries, delay);
else throw new TplFSErrorInvalid('create', (this.path != '' ? this.path + '/' : '') + path.join('/'), 'Invalid path'); else throw new TplFSErrorInvalid('create', (this.path != '' ? this.path + '/' : '') + path.join('/'), 'Invalid path');
}; };
@ -126,16 +126,21 @@ export function TplFS(client, parent, desc) {
else return await this.raw_cat(); else return await this.raw_cat();
}; };
this.raw_mkdir = async (name, tries=5, delay=1000) => { this.raw_mkdir = async (name, optimistic=true, tries=5, delay=1000) => {
if((desc.type == 'C') || (desc.type == 'P')) { if((desc.type == 'C') || (desc.type == 'P')) {
if(name == '.') return this; if(name == '.') return this;
else if(name == '..') return this.parent ? this.parent : this; else if(name == '..') return this.parent ? this.parent : this;
if(optimistic) {
var items = await client.TIU_TEMPLATE_GETITEMS(desc.IEN);
var item = items.find(x => x.name == name);
if(item) return new TplFS(client, this, item);
}
if(await lock(tries, delay) == '1') try { if(await lock(tries, delay) == '1') try {
var items = await client.TIU_TEMPLATE_GETITEMS(desc.IEN); var items = await client.TIU_TEMPLATE_GETITEMS(desc.IEN);
var item = items.find(x => x.name == name); var item = items.find(x => x.name == name);
if(item) return new TplFS(client, this, item); if(item) return new TplFS(client, this, item);
var nodeid = await client.TIU_TEMPLATE_CREATE_MODIFY(0, { '.01': name, '.02': '@', '.03': 'C', '.04': 'I', '.05': '0', '.08': '0', '.09': '0', '.1': '0', '.11': '0', '.12': '0', '.13': '0', '.14': '0', '.15': '@', '.16': '0', '.17': '@', '.18': '@', '.19': '@', '.06': desc.personal_owner, '2,1': '@', '5,1': '@' }); var nodeid = await client.TIU_TEMPLATE_CREATE_MODIFY(0, { '.01': name, '.02': '@', '.03': 'C', '.04': 'I', '.05': '0', '.08': '0', '.09': '0', '.1': '0', '.11': '0', '.12': '0', '.13': '0', '.14': '0', '.15': '@', '.16': '0', '.17': '@', '.18': '@', '.19': '@', '.06': desc.personal_owner, '2,1': '@', '5,1': '@' });
var nodes = (await client.TIU_TEMPLATE_GETITEMS(desc.IEN)).map(x => x.IEN); var nodes = items.map(x => x.IEN);
nodes.push(nodeid); nodes.push(nodeid);
await client.TIU_TEMPLATE_SET_ITEMS(desc.IEN, nodes); await client.TIU_TEMPLATE_SET_ITEMS(desc.IEN, nodes);
item = (await client.TIU_TEMPLATE_GETITEMS(desc.IEN)).find(x => (x.type == 'C') && (x.name == name)); item = (await client.TIU_TEMPLATE_GETITEMS(desc.IEN)).find(x => (x.type == 'C') && (x.name == name));
@ -147,9 +152,14 @@ export function TplFS(client, parent, desc) {
} else throw new TplFSErrorInvalid('mkdir', this.path, 'Not a directory'); } else throw new TplFSErrorInvalid('mkdir', this.path, 'Not a directory');
}; };
this.raw_create = async (name, data, tries=5, delay=1000) => { this.raw_create = async (name, data, optimistic=true, tries=5, delay=1000) => {
if((desc.type == 'C') || (desc.type == 'P')) { if((desc.type == 'C') || (desc.type == 'P')) {
if((name == '.') || (name == '..')) throw new TplFSErrorInvalid('create', (this.path != '' ? this.path + '/' : '') + name, 'Invalid path'); if((name == '.') || (name == '..')) throw new TplFSErrorInvalid('create', (this.path != '' ? this.path + '/' : '') + name, 'Invalid path');
if(optimistic) {
var items = await client.TIU_TEMPLATE_GETITEMS(desc.IEN);
var item = items.find(x => x.name == name);
if(item) return (new TplFS(client, this, item)).raw_update(data);
}
if(await lock(tries, delay) == '1') try { if(await lock(tries, delay) == '1') try {
var items = await client.TIU_TEMPLATE_GETITEMS(desc.IEN); var items = await client.TIU_TEMPLATE_GETITEMS(desc.IEN);
var item = items.find(x => x.name == name); var item = items.find(x => x.name == name);
@ -217,8 +227,8 @@ export function EncFS(fs, data_encrypt, data_decrypt, path_encrypt, path_decrypt
this.list = async (filter=null) => (await fs.list(filter)).map(x => new EncFS(x, data_encrypt, data_decrypt, path_encrypt, path_decrypt)); this.list = async (filter=null) => (await fs.list(filter)).map(x => new EncFS(x, data_encrypt, data_decrypt, path_encrypt, path_decrypt));
this.open = async (path) => new EncFS(await fs.open(await path_encrypt(path)), data_encrypt, data_decrypt, path_encrypt, path_decrypt); this.open = async (path) => new EncFS(await fs.open(await path_encrypt(path)), data_encrypt, data_decrypt, path_encrypt, path_decrypt);
this.mkdir = async (path, tries=5, delay=1000) => new EncFS(await fs.mkdir(await path_encrypt(path), tries, delay), data_encrypt, data_decrypt, path_encrypt, path_decrypt); this.mkdir = async (path, optimistic=true, tries=5, delay=1000) => new EncFS(await fs.mkdir(await path_encrypt(path), optimistic, tries, delay), data_encrypt, data_decrypt, path_encrypt, path_decrypt);
this.create = async (path, data, mkdir=false, tries=5, delay=1000) => new EncFS(await fs.create(await path_encrypt(path), await data_encrypt(data), mkdir, tries, delay), data_encrypt, data_decrypt, path_encrypt, path_decrypt); this.create = async (path, data, optimistic=true, mkdir=false, tries=5, delay=1000) => new EncFS(await fs.create(await path_encrypt(path), await data_encrypt(data), optimistic, mkdir, tries, delay), data_encrypt, data_decrypt, path_encrypt, path_decrypt);
this.remove = async (path, tries=5, delay=1000) => await fs.remove(await path_encrypt(path), tries, delay); this.remove = async (path, tries=5, delay=1000) => await fs.remove(await path_encrypt(path), tries, delay);
this.update = async (path, data) => new EncFS(await fs.update(await path_encrypt(path), await data_encrypt(data)), data_encrypt, data_decrypt, path_encrypt, path_decrypt); this.update = async (path, data) => new EncFS(await fs.update(await path_encrypt(path), await data_encrypt(data)), data_encrypt, data_decrypt, path_encrypt, path_decrypt);
this.cat = async (path) => await data_decrypt(await fs.cat(await path_encrypt(path))); this.cat = async (path) => await data_decrypt(await fs.cat(await path_encrypt(path)));