From 27f3803d2f295e8479a86f8b48b8c2ddc027a93c Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sat, 15 Feb 2025 18:24:26 +0300 Subject: [PATCH] Add vitastor_c_delete() and delete() to the node.js binding --- node-binding/addon.cc | 1 + node-binding/client.cc | 98 +++++++++++++++++++++++++++++++++------ node-binding/client.h | 15 ++++-- src/client/vitastor_c.cpp | 17 +++++++ src/client/vitastor_c.h | 2 + 5 files changed, 114 insertions(+), 19 deletions(-) diff --git a/node-binding/addon.cc b/node-binding/addon.cc index 6c5d5e32..7fe3371c 100644 --- a/node-binding/addon.cc +++ b/node-binding/addon.cc @@ -14,6 +14,7 @@ NAN_MODULE_INIT(InitAddon) Nan::SetPrototypeMethod(tpl, "read", NodeVitastor::Read); Nan::SetPrototypeMethod(tpl, "write", NodeVitastor::Write); + Nan::SetPrototypeMethod(tpl, "delete", NodeVitastor::Delete); Nan::SetPrototypeMethod(tpl, "sync", NodeVitastor::Sync); Nan::SetPrototypeMethod(tpl, "read_bitmap", NodeVitastor::ReadBitmap); Nan::SetPrototypeMethod(tpl, "on_ready", NodeVitastor::OnReady); diff --git a/node-binding/client.cc b/node-binding/client.cc index 63e4df91..68f01c0c 100644 --- a/node-binding/client.cc +++ b/node-binding/client.cc @@ -5,9 +5,10 @@ #define NODE_VITASTOR_READ 1 #define NODE_VITASTOR_WRITE 2 -#define NODE_VITASTOR_SYNC 3 -#define NODE_VITASTOR_READ_BITMAP 4 -#define NODE_VITASTOR_GET_INFO 5 +#define NODE_VITASTOR_DELETE 3 +#define NODE_VITASTOR_SYNC 4 +#define NODE_VITASTOR_READ_BITMAP 5 +#define NODE_VITASTOR_GET_INFO 6 #ifndef INODE_POOL #define INODE_POOL(inode) (uint32_t)((inode) >> (64 - POOL_ID_BITS)) @@ -133,12 +134,12 @@ NodeVitastorRequest* NodeVitastor::get_read_request(const Nan::FunctionCallbackI return req; } -// read(pool, inode, offset, len, callback(err, buffer, version)) +// read(pool, inode, offset, length, callback(err, buffer, version)) NAN_METHOD(NodeVitastor::Read) { TRACE("NodeVitastor::Read"); if (info.Length() < 5) - Nan::ThrowError("Not enough arguments to read(pool, inode, offset, len, callback(err, buffer, version))"); + Nan::ThrowError("Not enough arguments to read(pool, inode, offset, length, callback(err, buffer, version))"); NodeVitastor* self = Nan::ObjectWrap::Unwrap(info.This()); @@ -219,6 +220,52 @@ NAN_METHOD(NodeVitastor::Write) on_write_finish, req); } +NodeVitastorRequest* NodeVitastor::get_delete_request(const Nan::FunctionCallbackInfo & info, int argpos) +{ + uint64_t offset = get_ui64(info[argpos+0]); + uint64_t len = get_ui64(info[argpos+1]); + uint64_t version = 0; + if (!info[argpos+2].IsEmpty() && + !info[argpos+2]->IsFunction() && + info[argpos+2]->IsObject()) + { + auto key = Nan::New("version").ToLocalChecked(); + auto params = info[argpos+2].As(); + auto versionObj = Nan::Get(params, key).ToLocalChecked(); + if (!versionObj.IsEmpty()) + version = get_ui64(versionObj); + argpos++; + } + + v8::Local callback = info[argpos+2].As(); + auto req = new NodeVitastorRequest(this, callback); + + req->offset = offset; + req->len = len; + req->version = version; + + return req; +} + +// delete(pool, inode, offset, length, { version }?, callback(err)) +NAN_METHOD(NodeVitastor::Delete) +{ + TRACE("NodeVitastor::Delete"); + if (info.Length() < 5) + Nan::ThrowError("Not enough arguments to delete(pool, inode, offset, length, { version }?, callback(err))"); + + NodeVitastor* self = Nan::ObjectWrap::Unwrap(info.This()); + + uint64_t pool = get_ui64(info[0]); + uint64_t inode = get_ui64(info[1]); + + auto req = self->get_delete_request(info, 2); + + self->Ref(); + vitastor_c_delete(self->c, ((pool << (64-POOL_ID_BITS)) | inode), req->offset, req->len, req->version, + on_write_finish, req); +} + // sync(callback(err)) NAN_METHOD(NodeVitastor::Sync) { @@ -235,12 +282,12 @@ NAN_METHOD(NodeVitastor::Sync) vitastor_c_sync(self->c, on_write_finish, req); } -// read_bitmap(pool, inode, offset, len, with_parents, callback(err, bitmap_buffer)) +// read_bitmap(pool, inode, offset, length, with_parents, callback(err, bitmap_buffer)) NAN_METHOD(NodeVitastor::ReadBitmap) { TRACE("NodeVitastor::ReadBitmap"); if (info.Length() < 6) - Nan::ThrowError("Not enough arguments to read_bitmap(pool, inode, offset, len, with_parents, callback(err, bitmap_buffer))"); + Nan::ThrowError("Not enough arguments to read_bitmap(pool, inode, offset, length, with_parents, callback(err, bitmap_buffer))"); NodeVitastor* self = Nan::ObjectWrap::Unwrap(info.This()); @@ -436,12 +483,12 @@ NodeVitastorImage::~NodeVitastorImage() cli->Unref(); } -// read(offset, len, callback(err, buffer, version)) +// read(offset, length, callback(err, buffer, version)) NAN_METHOD(NodeVitastorImage::Read) { TRACE("NodeVitastorImage::Read"); if (info.Length() < 3) - Nan::ThrowError("Not enough arguments to read(offset, len, callback(err, buffer, version))"); + Nan::ThrowError("Not enough arguments to read(offset, length, callback(err, buffer, version))"); NodeVitastorImage* img = Nan::ObjectWrap::Unwrap(info.This()); @@ -452,12 +499,12 @@ NAN_METHOD(NodeVitastorImage::Read) img->exec_or_wait(req); } -// write(offset, buffer, { version }?, callback(err)) +// write(offset, buf: Buffer | Buffer[], { version }?, callback(err)) NAN_METHOD(NodeVitastorImage::Write) { TRACE("NodeVitastorImage::Write"); if (info.Length() < 3) - Nan::ThrowError("Not enough arguments to write(offset, buffer, { version }?, callback(err))"); + Nan::ThrowError("Not enough arguments to write(offset, buf: Buffer | Buffer[], { version }?, callback(err))"); NodeVitastorImage* img = Nan::ObjectWrap::Unwrap(info.This()); @@ -468,6 +515,22 @@ NAN_METHOD(NodeVitastorImage::Write) img->exec_or_wait(req); } +// delete(offset, length, { version }?, callback(err)) +NAN_METHOD(NodeVitastorImage::Delete) +{ + TRACE("NodeVitastorImage::Delete"); + if (info.Length() < 3) + Nan::ThrowError("Not enough arguments to delete(offset, length, { version }?, callback(err))"); + + NodeVitastorImage* img = Nan::ObjectWrap::Unwrap(info.This()); + + auto req = img->cli->get_delete_request(info, 0); + req->img = img; + req->op = NODE_VITASTOR_DELETE; + + img->exec_or_wait(req); +} + // sync(callback(err)) NAN_METHOD(NodeVitastorImage::Sync) { @@ -485,12 +548,12 @@ NAN_METHOD(NodeVitastorImage::Sync) img->exec_or_wait(req); } -// read_bitmap(offset, len, with_parents, callback(err, bitmap_buffer)) +// read_bitmap(offset, length, with_parents, callback(err, bitmap_buffer)) NAN_METHOD(NodeVitastorImage::ReadBitmap) { TRACE("NodeVitastorImage::ReadBitmap"); if (info.Length() < 4) - Nan::ThrowError("Not enough arguments to read_bitmap(offset, len, with_parents, callback(err, bitmap_buffer))"); + Nan::ThrowError("Not enough arguments to read_bitmap(offset, length, with_parents, callback(err, bitmap_buffer))"); NodeVitastorImage* img = Nan::ObjectWrap::Unwrap(info.This()); @@ -556,6 +619,13 @@ void NodeVitastorImage::exec_request(NodeVitastorRequest *req) req->iov_list.size() ? req->iov_list.size() : 1, NodeVitastor::on_write_finish, req); } + else if (req->op == NODE_VITASTOR_DELETE) + { + uint64_t ino = vitastor_c_inode_get_num(watch); + cli->Ref(); + vitastor_c_delete(cli->c, ino, req->offset, req->len, req->version, + NodeVitastor::on_write_finish, req); + } else if (req->op == NODE_VITASTOR_SYNC) { uint64_t ino = vitastor_c_inode_get_num(watch); @@ -967,7 +1037,7 @@ NodeVitastorKVListing::~NodeVitastorKVListing() kv->Unref(); } -// next(callback(err, value)?) +// next(callback(err, key, value)?) NAN_METHOD(NodeVitastorKVListing::Next) { TRACE("NodeVitastorKVListing::Next"); diff --git a/node-binding/client.h b/node-binding/client.h index 0a52fd7c..f3210062 100644 --- a/node-binding/client.h +++ b/node-binding/client.h @@ -15,13 +15,15 @@ class NodeVitastor: public Nan::ObjectWrap public: // constructor({ ...config }) static NAN_METHOD(Create); - // read(pool_id, inode, offset, len, callback(err, buffer, version)) + // read(pool_id, inode, offset, length, callback(err, buffer, version)) static NAN_METHOD(Read); // write(pool_id, inode, offset, buf: Buffer | Buffer[], { version }?, callback(err)) static NAN_METHOD(Write); + // delete(pool_id, inode, offset, length, { version }?, callback(err)) + static NAN_METHOD(Delete); // sync(callback(err)) static NAN_METHOD(Sync); - // read_bitmap(pool_id, inode, offset, len, with_parents, callback(err, bitmap_buffer)) + // read_bitmap(pool_id, inode, offset, length, with_parents, callback(err, bitmap_buffer)) static NAN_METHOD(ReadBitmap); // on_ready(callback(err)) static NAN_METHOD(OnReady); @@ -51,6 +53,7 @@ private: NodeVitastorRequest* get_read_request(const Nan::FunctionCallbackInfo & info, int argpos); NodeVitastorRequest* get_write_request(const Nan::FunctionCallbackInfo & info, int argpos); + NodeVitastorRequest* get_delete_request(const Nan::FunctionCallbackInfo & info, int argpos); friend class NodeVitastorImage; friend class NodeVitastorKV; @@ -62,13 +65,15 @@ class NodeVitastorImage: public Nan::ObjectWrap public: // constructor(node_vitastor, name) static NAN_METHOD(Create); - // read(offset, len, callback(err, buffer, version)) + // read(offset, length, callback(err, buffer, version)) static NAN_METHOD(Read); // write(offset, buf: Buffer | Buffer[], { version }?, callback(err)) static NAN_METHOD(Write); + // delete(offset, length, { version }?, callback(err)) + static NAN_METHOD(Delete); // sync(callback(err)) static NAN_METHOD(Sync); - // read_bitmap(offset, len, with_parents, callback(err, bitmap_buffer)) + // read_bitmap(offset, length, with_parents, callback(err, bitmap_buffer)) static NAN_METHOD(ReadBitmap); // get_info(callback({ num, name, size, parent_id?, readonly?, meta?, mod_revision, block_size, bitmap_granularity, immediate_commit })) static NAN_METHOD(GetInfo); @@ -129,7 +134,7 @@ class NodeVitastorKVListing: public Nan::ObjectWrap public: // constructor(node_vitastor_kv, start_key?) static NAN_METHOD(Create); - // next(callback(err, value)?) + // next(callback(err, key, value)?) static NAN_METHOD(Next); // close() static NAN_METHOD(Close); diff --git a/src/client/vitastor_c.cpp b/src/client/vitastor_c.cpp index f6fe95b9..61c9dab3 100644 --- a/src/client/vitastor_c.cpp +++ b/src/client/vitastor_c.cpp @@ -307,6 +307,23 @@ void vitastor_c_write(vitastor_c *client, uint64_t inode, uint64_t offset, uint6 client->cli->execute(op); } +void vitastor_c_delete(vitastor_c *client, uint64_t inode, uint64_t offset, uint64_t len, uint64_t check_version, + VitastorIOHandler cb, void *opaque) +{ + cluster_op_t *op = new cluster_op_t; + op->opcode = OSD_OP_DELETE; + op->inode = inode; + op->offset = offset; + op->len = len; + op->version = check_version; + op->callback = [cb, opaque](cluster_op_t *op) + { + cb(opaque, op->retval); + delete op; + }; + client->cli->execute(op); +} + void vitastor_c_read_bitmap(vitastor_c *client, uint64_t inode, uint64_t offset, uint64_t len, int with_parents, VitastorReadBitmapHandler cb, void *opaque) { diff --git a/src/client/vitastor_c.h b/src/client/vitastor_c.h index f5b1788d..ae4f1fec 100644 --- a/src/client/vitastor_c.h +++ b/src/client/vitastor_c.h @@ -63,6 +63,8 @@ void vitastor_c_read(vitastor_c *client, uint64_t inode, uint64_t offset, uint64 struct iovec *iov, int iovcnt, VitastorReadHandler cb, void *opaque); void vitastor_c_write(vitastor_c *client, uint64_t inode, uint64_t offset, uint64_t len, uint64_t check_version, struct iovec *iov, int iovcnt, VitastorIOHandler cb, void *opaque); +void vitastor_c_delete(vitastor_c *client, uint64_t inode, uint64_t offset, uint64_t len, uint64_t check_version, + VitastorIOHandler cb, void *opaque); void vitastor_c_read_bitmap(vitastor_c *client, uint64_t inode, uint64_t offset, uint64_t len, int with_parents, VitastorReadBitmapHandler cb, void *opaque); void vitastor_c_sync(vitastor_c *client, VitastorIOHandler cb, void *opaque);