LlUpdateKeyValue

来自人工智能助力教育知识百科
Wzc讨论 | 贡献2020年9月9日 (三) 11:16的版本
跳转至: 导航搜索

Template:Needs Translation/


函数名
Function: key llUpdateKeyValue( string k, string v, integer checked, string original_value );
参数:•字符串k(string k)–键值对的键

•字符串v(string v)–键值对的值。最多2047个字符,如果使用单声道,则为4095个字符。

•整数已检查(integer checked)–如果为真,则只有原始_值与键值存储区中的值匹配时才会进行更新。

•字符串原始值(string original_value)–要与键值存储区中的当前值进行比较的值。

如果checked设置为TRUE,则只有当原始值与键值存储区中的当前值匹配时,才会进行更新,否则数据服务器将返回失败,并返回错误XP_error_RETRY_update。这可以用来创建一个正在使用的标志,这样就可以实现原子性。

返回值:返回一个句柄(键),该句柄可用于标识相应的数据服务器事件,以确定此命令是成功还是失败以及结果。

截至2016年1月1日,LSO和Mono脚本的最大字节数分别为1011和4095。

使用llUpdateKeyValue更新不存在的密钥将不会生成XP\u ERROR\u key unt\u FOUND。相反,它将生成一个具有指定值的新键,就像您使用了llCreateKeyValue一样。

要使此功能正常工作,必须将脚本编译为一个体验Experience

注意事项
数据服务器回调参数为:

包含从llUpdateKeyValue返回的句柄的键 包含逗号分隔列表(cdl)的字符串。llDumpList2String([integer success]+组件); 组件根据请求的成功或失败而变化。 失败:cdl=llDumpList2String([0,整数错误],“,”) 成功:cdl=llDumpList2String([1,字符串值],“,”) 字符串组件

•整数成功–一个布尔值,指定事务是否成功(1)或否(0)。

•整数错误–描述操作失败原因的XP_error_x标志。

•字符串值–键值对的值。最多2047个字符,如果使用单声道,则为4095个字符。注意!此值可能包含逗号。

如果重新编译以前与体验相关联的脚本,但对缺乏将脚本编译为体验能力的客户端执行此操作,则该脚本将丢失关联的体验。 由于llKeysKeyValue以CSV格式返回密钥,建议密钥不包含逗号。

示例
示例1
key trans;
default
{
    state_entry()
    {
        trans = llUpdateKeyValue("FOO", "BLAH", TRUE, "BAR");
    }
 
    dataserver(key t, string value)
    {
        if (t == trans)
        {
            // our llUpdateKeyValue transaction is done
            list result = llCSV2List(value);
            if (llList2Integer(result, 0) == 1)
            {
                // the key-value pair was successfully updated
                llSay(0, "New key-value pair was successfully updated");
            }
            else
            {
                integer error = llList2Integer(result, 1);
                if(error == XP_ERROR_RETRY_UPDATE)
                    llSay(0, "Key-value update failed, checked value is out of date");
                else
                    llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(error) );
            }  
        }
    }
}

这个脚本演示了如何避免更新冲突(两个脚本同时更新存储),执行完全原子更新更为复杂。如果所有写入键值存储区的脚本都遵守虚拟锁($DB_lock),并且只在update_DB状态下进行更新,则所有写入都将是原子的。

key tid; list tids;

default {

   state_entry() {
       state lock_db;
   }

}

state lock_db {

   state_entry() {
       tid = llUpdateKeyValue("$DB_Lock", "LOCK", TRUE, "unlock");
   }
   dataserver(key did, string value) {
       if(did == tid) {
           string payload = llDeleteSubString(value, 0, 1);
           if(llGetSubString(value+",", 0, 1) == "1,"){
               llUpdateKeyValue("$DB_LockedBy", llDumpList2String([llGetOwner(),llGetKey(),llGetLinkKey(!!llGetLinkNumber()),llGetRegionName(),llGetPos(),llGetAttached()],":"), FALSE, "");
               state update_db;
           } else {
               integer err = (integer)payload;
               if(err == XP_ERROR_RETRY_UPDATE) {
                   llSay(0, "Database is already locked!");
               } else {
                   llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(err) );
               }
               state error;
           }
       }
   }

}

state update_db {

   state_entry() {
       tids = [
           llUpdateKeyValue("CatsPermissable", "5", FALSE, ""),
           llUpdateKeyValue("MonkeyMutations", "3", FALSE, ""),
           llUpdateKeyValue("CodFlavorSupport", "NEVER", FALSE, "")
       ];
   }
   dataserver(key did, string value) {
       integer i = llListFindList(tid, [did]);
       if(~i) {
           string payload = llDeleteSubString(value, 0, 1);
           if(llGetSubString(value+",", 0, 1) == "1,"){
               tids = llDeleteSubList(tids, i, i);
               if(tids == []) {
                   state unlock_db;
               }
           } else {
               llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage((integer)payload) );
               state error;
           }
       }
   }

}

state unlock_db {

   state_entry() {
       tid = llUpdateKeyValue("$DB_Lock", "unlock", TRUE, "LOCK");
   }
   dataserver(key did, string value) {
       if(did == tid) {
           string payload = llDeleteSubString(value, 0, 1);
           if(llGetSubString(value+",", 0, 1) == "1,"){
               state done;
           } else {
               integer err = (integer)payload;
               if(err == XP_ERROR_RETRY_UPDATE) {
                   llSay(0, "Someone has violated the database lock!");
               } else {
                   llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(err) );
               }
               state error;
           }
       }
   }

}

state done {

   state_entry(){;}

}

state error {

   state_entry(){;}

}

相关函数
llGetExperienceErrorMessage llCreateKeyValue llReadKeyValue llUpdateKeyValue llDeleteKeyValue llDataSizeKeyValue llKeyCountKeyValue llKeysKeyValue
相关事件