node-haystack Episode 11: node object of Volume
2016-09-11 16:36
369 查看
With the template, the representation of Volume now is simple and neat.
List of VolumeObject:
List of VolumeObject:
#define NODE_CLS_NAME_VOL "Volume" /*! \brief The node object of Volume. */ class VolumeObject : public NodeObjectTemplate<Volume> { public: using self_t = VolumeObject; using vol_t = shared_t<wrapped_t>; public: explicit VolumeObject(Volume* vol):Base(vol) { } IMPL_INIT_FUNC(NODE_CLS_NAME_VOL, { { "load", LoadVolume }, { "close", CloseVolume }, { "find", FindBlock }, { "addBlock", AddBlock }, { "rmBlock", RemoveBlock }, { "readData", ReadData }, { "recover", Recover }, { "verify", Verify }, }, { { "numOfBlock", BlockNum }, { "sizeOfVol", VolumeSize }, }) IMPL_NEW_FUNC(DEFAULT_NEW_FUNC()) private: /*! \brief Load volume from a file. */ static void LoadVolume(const js_arg_t& args) { PREPARE_FUNC(args, 3, vol) std::string path = help::to_string(args[0]); bool createNew = help::to_bool(args[1]); bool loadIndex = help::to_bool(args[2]); INIT_MT_CALLBACK(args, 3); vol->Load(path, createNew, loadIndex, [&, __CALLBACK_INFO__](int err) { MT_SCOPE() if (err) { MT_FIRE_CB_ERR(err) return ; } MT_FIRE_CB(help::mk_null(iso)); }); } /*! \brief Close volume. */ static void CloseVolume(const js_arg_t& args) { PREPARE_FUNC(args, 0, vol) INIT_MT_CALLBACK(args, 0) vol->Close([&, __CALLBACK_INFO__](int err) { MT_SCOPE() if (err) { MT_FIRE_CB_ERR(err); return ; } MT_FIRE_CB(help::mk_null(iso)); }); } /*! \brief Find specified block */ static void FindBlock(const js_arg_t& args) { PREPARE_FUNC(args, 1, vol) std::string key = help::to_string(args[0]); blk_idx_val_t idx; if (vol->FindBlock(key, &idx)) { FIRE_CB_ERR_MSG(args, 1, "NOT_FOUND"); return ; } FIRE_CB(args, 1, js::Null(iso), js_int::New(iso, idx.cookie), js_int::New(iso, idx.tag), js_int::New(iso, idx.size) ); } /*! \brief Add a new lbock. */ static void AddBlock(const js_arg_t& args) { PREPARE_FUNC(args, 6, vol) std::string key = help::to_string(args[0]); u32 cookie = args[1]->Int32Value(); u16 tag = args[2]->Int32Value(); u16 flag = args[3]->Int32Value(); if (!js_buf::HasInstance(args[4])) { THROW_JS_EXCEPTION(iso, "INVALID_BUFFER"); return ; } js_obj_t obj = args[4].As<js_obj>(); const char* buf = js_buf::Data(obj); size_t buf_len = js_buf::Length(obj); size_t len = args[5]->Uint32Value(); if (len > buf_len) { THROW_JS_EXCEPTION(iso, "LENGTH_OUT_OF_BOUNDS"); return ; } shared_t<vec_t<char>> data = mk_shared<vec_t<char>>({buf, buf + len}); INIT_MT_CALLBACK(args, 6) vol->AppendBlock(key, cookie, tag, flag, data, [&, __CALLBACK_INFO__](int err) mutable { MT_SCOPE() if (err) { MT_FIRE_CB_ERR(err); return ; } MT_FIRE_CB(js::Null(iso)); }); } /*! \brief Remove specified block. */ static void RemoveBlock(const js_arg_t& args) { PREPARE_FUNC(args, 2, vol) std::string key = help::to_string(args[0]); u32 cookie = args[1]->Uint32Value(); INIT_MT_CALLBACK(args, 2) vol->RemoveBlock(key, cookie, [&, __CALLBACK_INFO__](int err) { MT_SCOPE() if (err) { MT_FIRE_CB_ERR(err); return ; } MT_FIRE_CB(js::Null(iso)); }); } /*! \brief Read block data. */ static void ReadData(const js_arg_t& args) { PREPARE_FUNC(args, 1, vol) std::string key = help::to_string(args[0]); INIT_MT_CALLBACK(args, 1) vol->ReadBlockData(key, [&, __CALLBACK_INFO__](int err, shared_t<vec_t<char>>& data) { MT_SCOPE() if (err) { MT_FIRE_CB_ERR(err); return ; } size_t size = data->size(); char* buf = (char *)malloc(size); if (!buf) { MT_FIRE_CB_ERR_MSG("FAIL_TO_ALLOC_MEM"); return ; } MT_FIRE_CB( js::Null(iso), js_buf::New(iso, buf, size).ToLocalChecked(), js_int::New(iso, size) ); }); } /*! \brief Recover a volume. */ static void Recover(const js_arg_t& args) { PREPARE_FUNC(args, 2, vol) std::string src = help::to_string(args[0]); std::string dst = help::to_string(args[1]); INIT_MT_CALLBACK(args, 2) vol->Recover(src, dst, [&, __CALLBACK_INFO__](int err, const std::string& stat, u32 prog) { MT_SCOPE() if (err) { MT_FIRE_CB_ERR(err); return ; } MT_FIRE_CB({ help::mk_null(iso), help::mk_str(iso, stat), js_int::New(iso, prog) }); }); } /*! \brief Verify a volume. */ static void Verify(const js_arg_t& args) { PREPARE_FUNC(args, 2, vol) std::string src = help::to_string(args[0]); std::string dst = help::to_string(args[1]); INIT_MT_CALLBACK(args, 2) vol->Verify(src, dst, [&, __CALLBACK_INFO__](int err, const std::string& stat, u32 prog) { MT_SCOPE() if (err) { MT_FIRE_CB_ERR(err); return ; } MT_FIRE_CB({ help::mk_null(iso), help::mk_str(iso, stat), js_int::New(iso, prog) }); }); } /*! \brief Get the number of blocks. */ static void BlockNum(js_str_t prop_name, const js_prop_t& prop) { PREPARE_PROP(prop, vol, [&](vol_t vol) { return static_cast<u32>(vol == nullptr ? 0 : vol->BlockNum()); }); } /*! \brief Get file size of volume. */ static void VolumeSize(js_str_t prop_name, const js_prop_t& prop) { PREPARE_PROP(prop, vol, [&](vol_t vol ) { return js_num::New(iso, vol == nullptr ? (u64)0 : vol->FileSize()); }); } private: DECL_CTOR() }; // class
Project
Sorry, I omit this part.Test
A test code looks like this:var volume = require('../node-volume'); var random = require('../node-random'); var vol = new volume(); var vol_path = '/storage/node-volume-test.vol'; vol.load(vol_path, true, true, function(err) { if (err) { console.log('Failed to load volume:', err); return ; } var num = 1024; var buf = Buffer.allocUnsafe(1024).fill(0xAF); function add_more_blocks() { if (num == 0) { return vol.close(function(err) { if (err) { console.log('Failed to close volume:', err); return ; } console.log('Volume closed'); }); } num--; var key = random.nextUuid(); var cookie = random.next(); var tag = 0x1; var flag = 0; console.log('Add block:', 1024 - num); vol.addBlock(key, cookie, tag, flag, buf, buf.length, function(err) { if (err) { console.log('Failed to add block:', err); return ; } add_more_blocks(); }); } // fn add_more_blocks add_more_blocks(); });
相关文章推荐
- node-haystack Episode 5: Volume
- Testing Object-oriented Programs(Chapter 11 of Python 3 Object Oriented Programming)
- node-haystack Episode 3: Callback model in C++
- IT English Collection(11)of Object graph
- node-haystack Episode 7: Asynchronously manipulate blocks
- Guru of the Week 条款11:对象等同(Object Identity)问题
- node-haystack Episode 8: Simple Recovery And Verification
- 【leetcode】11 Remove Nth Node From End of List
- node-haystack Episode 9: Manipulate Volume
- node-haystack Episode - 12 : A Better Random Generator
- 【11】Delete a node in the middle of a single linked list
- node-haystack Episode 12: problem of C++ closure
- node-haystack Episode 1: What is it and why
- node-haystack Episode-4: Wrapper of libuv
- how to fetch all ancestor node id of a node(ezcontentobjecttreenode).
- node-haystack Episode 2: Asynchronous and Threading
- node-haystack Episode 10: Node.js add-on
- Handling IRPs 11: Life Cycle of a File Object
- LeetCoder_____Remove Nth Node From End of List(11)
- node-haystack Episode 6: Data Structure And Constants