皮皮网

【cf内存瞬移源码】【尚学堂课程源码】【linuxusb高速握手源码】源码key

2024-11-20 09:14:27 来源:推文系统源码

1.Unlua源码解析(附) 读源码的源码前置知识
2.Key的作用
3.vue中key的原理
4.Redis radix tree 源码解析
5.单片机c源码中uchar temp,key其中的key是什么意思
6.api key是指什么意思

源码key

Unlua源码解析(附) 读源码的前置知识

       在解析Unlua源码时,需要熟悉Lua的源码基本API和交互机制。以下为关键API及功能解析:

       1. lua_getfield(L,源码 k):获取指定表中由key k指向的值,压入栈顶。源码

       2. lua_gettop(L):返回栈顶元素的源码索引,即栈的源码cf内存瞬移源码大小。

       3. lua_rawget(L,源码 -2):与lua_getfield类似,获取t[k]的源码值压入栈顶,但不调用元方法。源码

       4. lua_rawset(L,源码 -4):设置t[k] = v,同样不通过元方法。源码

       5. lua_remove(L,源码 -2):移除栈中index为-2的内容,之后所有元素下移。源码

       6. Lua与C++交互机制:调用开始时,源码Lua参数依次压入栈;调用结束时,源码C++返回值压入栈,同时返回值数量。尚学堂课程源码

       在lua.h中,lua与C交互的API如下:

       1.1 lua_register:将C函数设置为全局名称的新值,允许Lua端调用。

       1.2 lua_gettop:返回栈顶元素的索引,用于获取栈大小。

       1.3 lua_pop:弹出栈中指定数量的值。

       1.4 lua_tolstring:将指定位置的值转换为C字符串,并返回字符串长度。

       1.5 lua_tostring:与lua_tolstring类似,但返回长度为NULL。

       1.6 lua_getfield:将表中key指向的值压入栈顶。

       1.7 luaL_getmetatable:获取指定表的元表并入栈。

       1.8 luaL_newmetatable:创建新元表并入栈,或重用已有。

       1.9 lua_getmetatable:获取指定索引处的表的元表。

       1. lua_pushstring:将字符串入栈,linuxusb高速握手源码Lua会做拷贝。

       1. lua_settable:设置表中key对应的值。

       1. lua_rawset:与lua_settable类似,不调用元方法。

       1. lua_gettable:从表中获取key对应的值。

       1. lua_rawget:与lua_gettable类似,不调用元方法。

       1. lua_pushinteger:将数字入栈。

       1. lua_pushlightuserdata:将指针入栈。

       1. lua_pushcclosure:创建闭包入栈。

       1. lua_pushvalue:复制指定位置的值入栈。

       1. lua_setmetatable:设置表元表。

       1. lua_getglobal:获取全局变量并入栈。

       1. lua_setglobal:设置全局变量值。

       1. lua_pushnil:入栈nil值。

       1. lua_upvalueindex:获取闭包中的asp去除广告源码upvalue。

       1. lua_touserdata:返回完整 userdata 或 light userdata 指针。

       1. lua_newtable:创建空表并入栈。

       1. lua_createtable:预分配空间后创建空表。

       1. lua_next:用于遍历表元素。

       1. lua_tolstring:将指定位置的值转换为C字符串。

       1. lua_tostring:与lua_tolstring类似,但不返回长度。

       1. lua_newuserdata:分配内存并创建 userdata。

       1. lua_call:调用Lua函数。

       1. lua_pcall:与lua_call类似,用于调用Lua函数。

       在Lua中,存在一些全局方法如rawset和rawget,用于直接写入或读取表元素而避免元方法的调用。

       综上所述,通过掌握这些API,如何取消源码注释开发者能有效利用Lua与C++的交互机制,实现复杂、高效的数据处理和逻辑交互。

Key的作用

       1、key的作用主要是为了更高效的对比虚拟DOM中的某个节点是否是相同节点。

        2、Vue在patch过程中判断两个节点是否是相同节点key是一个必要条件,渲染一组列表时,key往往是唯一标识,所以如果不定义key的话,Vue只能认为比较的两个节点是同一个,哪怕它们实际上不是,这导致了频繁更新元素,使得整个patch过程比较低效,影响性能。

        3、实际使用中在渲染一组列表时key必须设置,而且必须是唯一标识,应该避免使用数组索引作为key,这可能导致一些隐蔽的bug;Vue中在使用相同标签元素过渡切换时,也会使用key属性,其目的也是为了让Vue可以区分它们,否则Vue只会替换其内部属性而不会触发过渡效果。

        4、从源码中可以知道,Vue判断两个节点是否相同时主要判断两者的key和元素类型等,因此如果不设置,它的值就是是undefined,则可能永远认为这是两个相同节点,只能去做更新操作,这造成了大量的DOM更新操作,明显是不可取的。

vue中key的原理

       ä¸€ã€Key是什么

       å¼€å§‹ä¹‹å‰ï¼Œæˆ‘们先还原两个实际工作场景

       å½“我们在使用v-for时,需要给单元加上key

<ul><liv-for="iteminitems":key="item.id">...</li></ul>

       ç”¨+newDate()生成的时间戳作为key,手动强制触发重新渲染

<Comp:key="+newDate()"/>

       é‚£ä¹ˆè¿™èƒŒåŽçš„逻辑是什么,key的作用又是什么?一句话来讲key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确,更快的找到对应的vnode节点

场景背后的逻辑

       å½“我们在使用v-for时,需要给单元加上key

       å¦‚果不用key,Vue会采用就地复地原则:最小化element的移动,并且会尝试尽最大程度在同适当的地方对相同类型的element,做patch或者reuse。

       å¦‚果使用了key,Vue会根据keys的顺序记录element,曾经拥有了key的element如果不再出现的话,会被直接remove或者destoryed用+newDate()生成的时间戳作为key,手动强制触发重新渲染

       å½“拥有新值的rerender作为key时,拥有了新key的Comp出现了,那么旧keyComp会被移除,新keyComp触发渲染

二、设置key与不设置key区别

       ä¸¾ä¸ªä¾‹å­ï¼šåˆ›å»ºä¸€ä¸ªå®žä¾‹ï¼Œ2秒后往items数组插入数据

<body><divid="demo"><pv-for="iteminitems":key="item">{ { item}}</p></div><scriptsrc="../../dist/vue.js"></script><script>//创建实例constapp=newVue({ el:'#demo',data:{ items:['a','b','c','d','e']},mounted(){ setTimeout(()=>{ this.items.splice(2,0,'f')//},);},});</script></body>

       åœ¨ä¸ä½¿ç”¨key的情况,vue会进行这样的操作:

       åˆ†æžä¸‹æ•´ä½“流程:

       æ¯”较A,A,相同类型的节点,进行patch,但数据相同,不发生dom操作

       æ¯”较B,B,相同类型的节点,进行patch,但数据相同,不发生dom操作

       æ¯”较C,F,相同类型的节点,进行patch,数据不同,发生dom操作

       æ¯”较D,C,相同类型的节点,进行patch,数据不同,发生dom操作

       æ¯”较E,D,相同类型的节点,进行patch,数据不同,发生dom操作

       å¾ªçŽ¯ç»“束,将E插入到DOM中一共发生了3次更新,1次插入操作

       åœ¨ä½¿ç”¨key的情况:vue会进行这样的操作:

       æ¯”较A,A,相同类型的节点,进行patch,但数据相同,不发生dom操作

       æ¯”较B,B,相同类型的节点,进行patch,但数据相同,不发生dom操作

       æ¯”较C,F,不相同类型的节点

       æ¯”较E、E,相同类型的节点,进行patch,但数据相同,不发生dom操作

       æ¯”较D、D,相同类型的节点,进行patch,但数据相同,不发生dom操作

       æ¯”较C、C,相同类型的节点,进行patch,但数据相同,不发生dom操作

       å¾ªçŽ¯ç»“束,将F插入到C之前一共发生了0次更新,1次插入操作通过上面两个小例子,可见设置key能够大大减少对页面的DOM操作,提高了diff效率

设置key值一定能提高diff效率吗?

       å…¶å®žä¸ç„¶ï¼Œæ–‡æ¡£ä¸­ä¹Ÿæ˜Žç¡®è¡¨ç¤ºå½“Vue.js用v-for正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时DOM状态(例如:表单输入值)的列表渲染输出建议尽可能在使用?v-for?时提供?key,除非遍历输出的DOM内容非常简单,或者是刻意依赖默认行为以获取性能上的提升

三、原理分析

       æºç ä½ç½®ï¼šcore/vdom/patch.js里判断是否为同一个key,首先判断的是key值是否相等如果没有设置key,那么key为undefined,这时候undefined是恒等于undefined

functionsameVnode(a,b){ return(a.key===b.key&&((a.tag===b.tag&&a.isComment===b.isComment&&isDef(a.data)===isDef(b.data)&&sameInputType(a,b))||(isTrue(a.isAsyncPlaceholder)&&a.asyncFactory===b.asyncFactory&&isUndef(b.asyncFactory.error))))}

       updateChildren方法中会对新旧vnode进行diff,然后将比对出的结果用来更新真实的DOM

functionupdateChildren(parentElm,oldCh,newCh,insertedVnodeQueue,removeOnly){ ...while(oldStartIdx<=oldEndIdx&&newStartIdx<=newEndIdx){ if(isUndef(oldStartVnode)){ ...}elseif(isUndef(oldEndVnode)){ ...}elseif(sameVnode(oldStartVnode,newStartVnode)){ ...}elseif(sameVnode(oldEndVnode,newEndVnode)){ ...}elseif(sameVnode(oldStartVnode,newEndVnode)){ //Vnodemovedright...}elseif(sameVnode(oldEndVnode,newStartVnode)){ //Vnodemovedleft...}else{ if(isUndef(oldKeyToIdx))oldKeyToIdx=createKeyToOldIdx(oldCh,oldStartIdx,oldEndIdx)idxInOld=isDef(newStartVnode.key)?oldKeyToIdx[newStartVnode.key]:findIdxInOld(newStartVnode,oldCh,oldStartIdx,oldEndIdx)if(isUndef(idxInOld)){ //NewelementcreateElm(newStartVnode,insertedVnodeQueue,parentElm,oldStartVnode.elm,false,newCh,newStartIdx)}else{ vnodeToMove=oldCh[idxInOld]if(sameVnode(vnodeToMove,newStartVnode)){ patchVnode(vnodeToMove,newStartVnode,insertedVnodeQueue,newCh,newStartIdx)oldCh[idxInOld]=undefinedcanMove&&nodeOps.insertBefore(parentElm,vnodeToMove.elm,oldStartVnode.elm)}else{ //samekeybutdifferentelement.treatasnewelementcreateElm(newStartVnode,insertedVnodeQueue,parentElm,oldStartVnode.elm,false,newCh,newStartIdx)}}newStartVnode=newCh[++newStartIdx]}}...}原文:/post/

Redis radix tree 源码解析

       Redis 实现了不定长压缩前缀的 radix tree,用于集群模式下存储 slot 对应的所有 key 信息。本文解析在 Redis 中实现 radix tree 的核心内容。

       核心数据结构的定义如下:

       每个节点结构体 (raxNode) 包含了指向子节点的指针、当前节点的 key 的长度、以及是否为叶子节点的标记。

       以下是插入流程示例:

       场景一:仅插入 "abcd"。此节点为叶子节点,使用压缩前缀。

       场景二:在 "abcd" 之后插入 "abcdef"。从 "abcd" 的父节点遍历至压缩前缀,找到 "abcd" 空子节点,插入 "ef" 并标记为叶子节点。

       场景三:在 "abcd" 之后插入 "ab"。ab 为 "abcd" 的前缀,插入 "ab" 为子节点,并标记为叶子节点。同时保留 "abcd" 的前缀结构。

       场景四:在 "abcd" 之后插入 "abABC"。ab 为前缀,创建 "ab" 和 "ABC" 分别为子节点,保持压缩前缀结构。

       删除流程则相对简单,找到指定 key 的叶子节点后,向上遍历并删除非叶子节点。若删除后父节点非压缩且大小大于1,则需处理合并问题,以优化树的高度。

       合并的条件涉及:删除节点后,检查父节点是否仍为非压缩节点且包含多个子节点,以此决定是否进行合并操作。

       结束语:云数据库 Redis 版提供了稳定可靠、性能卓越、可弹性伸缩的数据库服务,基于飞天分布式系统和全SSD盘高性能存储,支持主备版和集群版高可用架构。提供全面的容灾切换、故障迁移、在线扩容、性能优化的数据库解决方案,欢迎使用。

单片机c源码中uchar temp,key其中的key是什么意思

       根据电路的排布,temp和key分别代表行和列,行、列都确定后,就可以定位是那个按键响应了~

       按键按下后,都会进入key4x4()的函数,先用temp来区分出是哪一行(列),再用key来区分具体为那一列(行),从而确定动作按键的具体位置;

api key是指什么意思

       API Key,简单来说,就是一个特殊的密钥,它是应用程序编程接口(Application Programming Interface,API)的核心组成部分。API是软件系统间交流的桥梁,用来定义通信规则。API Key是访问这些接口的必要凭证,用于验证调用者身份,防止未经授权的访问。它通常表现为一个长字符串,有时隐含在URL或请求头中,与特定的应用程序绑定,可能包括公钥和私钥的区分,私钥仅在服务器间通信时使用以确保安全。

       在使用API Key时,有几点需要注意:首先,API Key是敏感信息,切勿随意分享或赠予他人,以防止潜在的安全风险。其次,避免在源代码中直接存储API Key,以防泄露。定期更换API Key是增强安全性的有效手段。此外,要强化服务器防护,防止病毒、黑客和恶意攻击。最后,API Key主要作为身份验证工具,而非授权机制,它类似用户名和密码,是访问系统的关键。通常,它会被放置在授权标头、基本身份验证等位置。妥善保管API Key,以维护数据隐私和系统安全。