1.【PostgreSQL内核】Trigger的码的码一生
2.intel14代i9编译linux内核源码需要多久?
3.主力筹码趋向指标源码
4.iOS 14 开发者版本泄露源头:是哪款 iPhone 和如何流出的?
5.iOS 14泄密:iPhone 9配置如何,新iPad Pro的源码AR功能有何亮点?
6.定义一个一维整型数组,有10个元素。(5,补码4,9,2,6,11,14,8,10,16)?
【PostgreSQL内核】Trigger的一生
本文简要介绍 PostgreSQL 数据库的 Trigger 从创建、存储、和反触发、码的码执行、源码aj手写源码修改到删除的补码过程,贯穿 Trigger 的和反一生。
文中引用的码的码函数、结构体来源于 PG 源码,源码分支为 REL__STABLE,补码对应的和反 commit id 如下。此外还引用了 PG 官方文档。码的码
触发器简介
Trigger 即触发器,源码它可以在特定事件发生时,补码对数据库中的对象执行特定操作:
根据触发事件的不同,PG 的触发器分为两类:
不同数据库中触发器的分类有所不同,比如 Oracle 分为 DML Trigger 和 System Trigger,SQL Server 分为 DML Trigger、DDL Trigger 和 Login Trigger,不论其如何划分,多数都可以与 PG 的触发器对应上。
创建触发器语法
首先介绍创建触发器的 SQL 和 PLpgSQL 语法。
Trigger
根据 PG 官方文档,创建 Trigger 的语法如下:
下面以表 t1、t2 为例创建一个简单的触发器示例。表的定义如下:
触发器定义如下,是表 t1 上的行级触发器,对 t1 进行 INSERT 之后会触发,并执行 insert_into_t2 函数,将插入到 t1 的数据也插入到 t2。
insert_into_t2 函数定义如下,其中引用了上下文信息 NEW,表示插入到 t1 的数据,并将其插入到 t2。
Event Trigger
创建 Event Trigger 的语法如下,相比 Trigger 的语法要简单很多
以下是 PG 官方文档中的一个简单示例,该 Event Trigger 可以在任何 DDL 语句执行之前触发,并抛出异常,禁止执行任何 DDL 语句。
创建流程
简单介绍创建触发器时 PG 内核中的函数调用流程。
Trigger
CREATE TRIGGER 命令都属于 DDL 语句,restapi文档 源码所以会进入 DDL 的处理流程,关键的调用路径为: ProcessUtilitySlow-->CreateTrigger-->CreateTriggerFiringOn,CreateTriggerFiringOn 函数代码超过 行,因此只介绍其中的关键步骤:
Event Trigger
CREATE EVENT TRIGGER 的关键调用路径为: standard_ProcessUtility-->CreateEventTrigger,该函数流程相对简单很多:
触发器的存储
用户创建的触发器必须持久化到数据库中,具体的存储位置是触发器相关的系统表中。
Trigger
Trigger 存储在 pg_trigger 系统表中,表中的关键字段如下,包含触发器所在的表、触发器名、触发器调用的函数、是否可推迟等属性。总之,通过 CREATE TRIGGER 创建触发器时指定的任何信息都会存储到系统表中。
pg_trigger 系统表的各个字段在内存中用Trigger 结构体表示,定义如下,可见其成员变量与 pg_trigger 的属性是一一对应的。
在内存中的 relcache(表缓存)中也同样保存有 Trigger 的信息:
Event Trigger
Event Trigger 存储在 pg_event_trigger 系统表中,关键字段如下,包含触发器名、调用的函数等信息。与 Trigger 不同的是,这里并不包含触发器所在的表,因为 Event Trigger 不属于任何一个表。
触发过程
触发器会在特定事件场景下被触发,它识别这些事件的方式也很简单,就是在对应事件的代码处调用触发器函数。
Trigger
对于普通的触发器,触发时机是 INSERT、UPDATE、DELETE 等操作之前或者之后,所以在 PG 的执行器阶段触发,多数在 ProcessQuery-->ExecutorRun-->ExecModifyTable 函数中
我们将执行触发操作的函数称为“触发器的执行函数”,各类触发器的执行函数命名格式比较统一,在此列举几种:
以ExecBRInsertTriggers 为例说明触发过程:
Event Trigger
事件触发器支持的事件仅有 ddl_command_start、ddl_command_end、table_rewrite 和 sql_drop 这四类,分别对应四个执行函数,其触发时机说明如下:
以 EventTriggerDDLCommandStart 为例说明触发过程:
调用功能函数
用户在创建触发器的 EXECUTE { FUNCTION | PROCEDURE } function_name 语句中指定了该触发器要执行的功能函数。在触发器被触发后,会执行该函数。laveral源码解析
Trigger
在执行器阶段触发时,ResultRelInfo 结构体中存有表上的各项信息,其中就包括表上的触发器、函数等,所以直接从中就可以拿到触发器信息。关键结构体为 ResultRelInfo、TriggerDesc、Trigger,其嵌套关系如下:
将ResultRelInfo 中获取的 Trigger 结构体的全部内容都填充到 TriggerData 结构体,ExecCallTriggerFunc 函数再从 TriggerData 中获取函数 oid,并执行该函数。
TriggerData 结构体定义如下,其中除了 Trigger 以外还保存了各种执行上下文信息,heap 表信息等,与函数的执行有关。
TriggerData 最终会保存到PLpgSQL_execstate 中,这是 PLpgSQL 执行过程中的一个重要结构体:
触发器的功能函数执行的方法与普通的 PLpgSQL 函数、存储过程执行方法是类似的,关键调用路径是: ExecCallTriggerFunc-->plpgsql_call_handler-->plpgsql_exec_trigger-->exec_toplevel_block-->exec_stmt_block-->…………
Event Trigger
对于事件触发器,在触发阶段的EventTriggerCommonSetup 函数中,通过 EventCacheLookup 从缓存中查找触发器功能函数,然后在 EventTriggerInvoke 中根据触发器函数的 oid 进行调用。
EventTriggerCommonSetup 中还会填充 EventTriggerData 结构体,其中保存了调用过程中的一些关键信息:
与普通触发器的 TriggerData 结构一样,EventTriggerData 结构体也会保存到PLpgSQL_execstate 中,在 PLpgSQL 执行过程中使用:
事件触发器的功能函数实际执行步骤与普通触发器也基本相同,关键调用路径为: ExecCallTriggerFunc-->plpgsql_call_handler-->plpgsql_exec_event_trigger-->exec_toplevel_block-->exec_stmt_block-->…………
修改触发器
使用 ALTER 语句修改触发器的定义
Trigger
根据 PG 官方文档,ALTER TRIGGER 的语法如下:
仅支持重命名和修改依赖的插件。
重命名触发器的关键调用流程为:standard_ProcessUtility-->ExecRenameStmt-->renametrig,基本原理也是读取 pg_trigger 系统表的信息,修改以后写回系统表。
修改触发器依赖插件的关键调用流程为:standard_ProcessUtility-->ExecAlterObjectDependsStmt,会修改 pg_depend 系统表。
Event Trigger
根据 PG 官方文档,ALTER EVENT TRIGGER 语法为:
支持对事件触发器进行重命名、禁用、启用、修改 owner 的操作。
ALTER TRIGGER 的关键函数是AlterEventTrigger,其内容较为简单:
删除触发器
使用 DROP 语句删除触发器
Trigger
PG 文档中 DROP TRIGGER 语法如下:
删除触发器的关键函数是RemoveTriggerById,调用流程如下: ProcessUtilitySlow-->ExecDropStmt-->RemoveObjects-->performMultipleDeletions-->deleteObjectsInList-->deleteOneObject-->doDeletion-->RemoveTriggerById
RemoveTriggerById 函数流程:
Event Trigger
PG 文档中 DROP EVENT TRIGGER 语法如下:
删除事件触发器的简约房产源码关键函数是DropObjectById,这是一个公用的函数,可以删除多种类型的对象。
调用流程如下: ProcessUtilitySlow-->ExecDropStmt-->RemoveObjects-->performMultipleDeletions-->deleteObjectsInList-->deleteOneObject-->doDeletion-->DropObjectById
intel代i9编译linux内核源码需要多久?
编译Linux内核源码所需时间受多种因素影响,包括硬件性能、内核版本、编译选项等。以Intel第代i9处理器为例,其性能相较于上一代显著提升,能为编译过程提供更强支持。根据历史数据,著名Linux内核开发者Linus Torvalds在使用Intel i9-K时,编译过程大约需要秒,而使用AMD Threadripper X时,编译时间则缩短至大约秒。
然而,Linus Torvalds本人对顶级旗舰处理器并不“舍得”,更未购买当时性能最强的X。这表明顶级硬件并非编译Linux内核的必要条件。实际上,即便是使用中高端Intel i9处理器,也已能显著减少编译时间。
编译Linux内核的性能优化同样至关重要。合理的编译选项、并行编译、预编译等策略均能有效提升编译效率。同时,保持内核版本的适度更新,避免过时的代码和功能,也能减少编译所需时间。
综上所述,使用Intel第代i9处理器编译Linux内核源码时,预估的编译时间可能介于秒至秒之间,实际时间则需根据具体配置和优化策略而定。而通过硬件升级、优化编译策略和保持内核版本更新,均可有效缩短编译时间,提升开发效率。
主力筹码趋向指标源码
DMI指标又叫动向指标或趋向指标,是一种中长期股市技术分析(Technical Analysis)方法。学习炒股,要懂得股票的老张 博客 源码专业术语,还有炒股技巧也要掌握,那么主力筹码趋向指标源码是什么呢?DMI指标是通过分析股票价格在涨跌过程中买卖双方力量均衡点的变化情况,即多空双方的力量的变化受价格波动的影响而发生由均衡到失衡的循环过程,从而提供对趋势判断依据的一种技术指标。
dmi指标如何
主力筹码趋向指标源码:N:=;M:=6;
MTR:=SUM(MAX(MAX(HIGH-LOW,ABS(HIGH-REF(CLOSE,1))),ABS(REF(CLOSE,1)-LOW)),N);
HD:=HIGH-REF(HIGH,1);
LD:=REF(LOW,1)-LOW;
DMP:=SUM(IF(HD>0HD>LD,HD,0),N);
DMM:=SUM(IF(LD>0LD>HD,LD,0),N);
PDI:=DMP*/MTR;
MDI:=DMM*/MTR;
ADX:=MA(ABS(MDI-PDI)/(MDI+PDI)*,M);
ADXR:=(ADX+REF(ADX,M))/2;
XG:CROSS(PDI,MDI)AND CROSS(PDI,ADX)AND CROSS(PDI,ADXR)。
至于dmi指标怎么看?dmi指标是一种“价格趋势”分析指标,有白、红、绿、黄四条线,分别代表四种状态,那就是买入、卖出、持股观望、持币观望。当股价走势向上发展,而同时+DI从下方向上突破-DI时,表明市场上有新多买家进场,为买入信号,如果ADX伴随上升,则预示股价的涨势可能更强劲。
iOS 开发者版本泄露源头:是哪款 iPhone 和如何流出的?
iOS 的重大漏洞源头疑云被揭示
近期,有迹象表明iOS 的一个关键漏洞源头可能已被披露,这一泄漏事件让许多未公开的功能提前数月曝光。根据Motherboard的独家报道,早在几个月前,iOS 的早期版本已经在安全圈子内部广泛流传,比苹果原定的发布时间至少提前了八个月。 消息人士透露,自2月份以来,iOS 源代码的访问权限被破解,允许黑客和安全研究员深入探索其内部结构。据报道,"整个操作系统版本的完整副本被泄露,随后迅速扩散",这为寻找早期漏洞提供了机会。 至少五位知情者透露,漏洞的根源可以追溯至去年月的开发者版iPhone ,这些设备是从中国供应商处以数千美元的价格购得。买家获取了iOS 的内部版本后,将其分发给越狱开发者,从而引发了今年初一系列iOS 泄漏的序幕。 泄露的代码揭示了苹果的一些内部计划,例如,疑似筹备中的耳罩式耳机、一个名为Clips的应用程序,以及可能通过iOS、watchOS和tvOS生态系统扩展的健身视频功能。对于这些潜在的革新,Motherboard已寻求安全专家的评估,Ryan Duff表示:“虽然它可能还处于预发布阶段,变化频繁,但它提供了一个深入了解iOS文件系统的宝贵窗口。它并不意味着轻松的越狱,但无疑,泄露的信息比我们通常所见的对即将发布的新版iOS来说,更为详尽丰富。” 这一漏洞的出现,不仅引发了关于苹果安全措施的质疑,也预示着未来的iOS更新将面临更严峻的挑战,用户和开发者都需密切关注苹果的回应与应对策略。iOS 泄密:iPhone 9配置如何,新iPad Pro的AR功能有何亮点?
苹果新品大曝光!iOS 揭示iPhone 9、新iPad Pro等新品细节
尽管iPhone 9尚未公开,但其存在已被iOS 的源代码证实。开发者挖掘出的证据包含新iPad Pro、iPhone 9、AirTags以及升级版Apple TV遥控器,苹果可能在一次官方行动中一并发布。 在iOS 的代码中,对iPhone 9的描述较为谨慎,但透露了Touch ID指纹识别的继续使用,以及与iPhone 8相似的外观,但配置升级为A处理器和3GB内存,性能提升明显。 新iPad Pro的亮点在于,据透露,它将采用iPhone Pro的后置三摄配置,且配备ToF 3D传感器,以增强AR体验。苹果还计划推出一款名为Gobi的AR应用,通过iPhone屏幕帮助用户更深入地了解周围环境,如在Apple Store内查看产品详细信息。 苹果还计划推出健身应用Seymour,支持iPhone、Apple Watch、iPad和Apple TV,用户可以下载健身视频进行锻炼指导,并跟踪健身进度,强化健康生活功能。 AirTags虽然信息不多,但确认其作为一款小巧的NFC防丢配件,与苹果设备联动,其实际功能将成为焦点。 最后,全新Apple TV遥控器预计与新电视同步发布,时间可能定于秋季。让我们拭目以待,苹果如何将这些新品逐一呈现给用户。定义一个一维整型数组,有个元素。(5,4,9,2,6,,,8,,)?
C语言代码和运行结果如下:输出符合要求,望采纳~
附源码:
#include <stdio.h>
int diff(int x, int y) { // 求差函数
if (x > y)
return x - y;
else
return y - x;
}
int main() {
int a[] = { 5,4,9,2,6,,,8,,}; // 定义数组并初始化
int max = a[0], min = a[0], sum, i;
printf("下标为奇数的元素: ");
for (i = 1; i < ; i++) {
if (i % 2 == 1) // 输出下标为奇数的元素
printf("%d ", a[i]);
if (a[i] > max) // 求最大值
max = a[i];
else if (a[i] < min) // 求最小值
min = a[i];
}
sum = diff(min, max); // 最大值与最小值的差,保证结果非负
printf("\n最大值max=%d, 最小值min=%d, 最大值与最小值的差sum=%d\n", max, min, sum);
return 0;
}
Android HWUI 源码研究 View Canvas RenderThread ViewRootImpl skia
HUWUI是Android系统中负责应用可视化元素绘制的核心组件,其架构主要在C++层实现,从Java层接收View绘制信息,通过唯一的渲染线程使用skia技术完成渲染任务。整体上,从应用程序到UI线程,再到渲染线程,形成了清晰的层级关系。
HUWUI的构建主要包括三个核心类,它们分别是:RecordingCanvas、Canvas、RenderNode、RenderProxy、RenderThread、CanvasContext、IRenderPipeline。在Java层,主要涉及两类Canvas,RecordingCanvas用于记录绘制指令,Canvas则是直接用于渲染。RecordingCanvas在构造时创建,而Canvas在调用时创建。这两个类在C++层分别对应SkiaRecordingCanvas和SkiaCanvas,后者直接引用SkCanvas。
在全局循环中,UI线程与渲染线程之间的协同操作至关重要。具体流程包括:新创建Activity后,附着到对应的PhoneWindow,然后调用PhoneWindow的setContentView方法,将View添加到DecorView作为子节点。接着,DecorView与ViewRootImpl对接,完成View的更新与渲染。整个过程包含了measure、layout和draw等复杂子流程。
渲染线程创建与核心对象紧密关联,主要包括RenderProxy、RenderThread和DrawFrameTask。RenderProxy负责Java层信息的衔接,RenderThread作为进程唯一的渲染线程,持有DrawFrameTask和CanvasContext,完成一帧的绘制任务。指令记录流程的核心在于使用C++层的RecordingCanvas将View属性和绘制信息记录到DisplayList中,进而完成指令的渲染。
Surface、ANativeWindow、EGLSurface的创建流程在ViewRootImpl的performTraversals函数中初始化。ReliableSurface的封装和EGL与Skia环境的创建主要在RenderThread的requireGlContext函数中实现。从源码分析,这一过程通常在三个地方调用。
View树与RenderNode树之间的协作关系明确,一个Application进程对应多个Activity,每个Activity与一个PhoneWindow绑定,PhoneWindow持有DecorView,DecorView对应一个ViewRootImpl,而ViewRootImpl与ThreadedRender模块对接。ThreadedRender与C++层的RenderProxy一一对应,RenderProxy持有关键对象,如RenderThread、CanvasContext、DrawFrameTask等。RenderThread是单例模式,进程唯一,负责一帧绘制的逻辑。
在RenderPipeline模块中,关键操作包括makeCurrent、draw和swapBuffers。Native Canvas在这一过程中扮演了桥梁角色,接收Java API调用,而RecordingCanvas完成Op记录,最终DisplayListData存储这些Op。
skia的核心资源主要在三个使用场景中发挥作用,具体细节需深入分析,这些资源对于实现高效、稳定的渲染效果至关重要。
Android Cuttlefish模拟器(Android Automotive)
为了在实际工作和学习中体验Android Automotive的多屏区划和特殊交互,本文将指导如何基于Android 源码自建一个 Automotive 模拟器,特别针对网络受限的用户,通过清华大学开源软件镜像站获取AOSP源码。
首先,准备下载AOSP源码。在~/bin目录下创建repo工具,并通过curl获取存储网上的资源,确保可执行权限。具体步骤可参考"不懂内核的小潘"的文章中关于repo命令的总结。
接下来,访问mirrors.tuna.tsinghua.edu.cn下载android repo仓库,由于代码隐藏在.repo目录中,下载后解压并使用repo sync命令获取完整目录。找到对应版本,如android-.0.1_r1。
编译前,请确保源码目录有足够的空间(至少GB以上,我编译的x_版本耗用超过GB)。在源码根目录下,了解Cuttlefish与默认模拟器的区别,Cuttlefish更侧重底层调试,而emulator更偏向应用测试。
通过lunch命令选择构型,如aosp_cf_x__auto-userdebug,其中cf表示Cuttlefish,auto专为Automotive设计。选择x版本,速度较快,arm版本则表现不佳。启动模拟器需要执行相应的命令,如launch_cvd,注意配置环境变量并保持网络连接。
成功启动后,在浏览器访问https://localhost:/,模拟器会显示两个车载屏幕。当需要关闭模拟器时,运行stop_cvd命令。对于想使用SDK自带模拟器的用户,可以尝试lunch sdk_car_x_-userdebug 构型,直接通过emulator启动。
在编译过程中,生成的adb工具可用于与模拟器进行交互,具体操作可参考Android开发者文档。至此,你已经成功搭建并启动了Android Automotive模拟器,可以开始你的开发和调试工作。