深度优先

这个家伙好懒,除了文章什么都没留下

0%

1
2
3
4
作者:JensenWong
链接:https://www.jianshu.com/p/a68ff08f5856
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

把SVN上的代码仓库迁移到Gitlab上,实际上就是把SVN仓库转变成Git仓库,并且希望能保留原SVN仓库的Commit等历史记录,这一点很重要。
SVN迁移到Gitlab需要安装git-svn

1
2
# yum install -y git-svn

保留原SVN仓库的Commit等历史记录,需要获取到SVN使用的作者名字列表,为了获得 SVN 使用的作者名字列表,可以在checkout到本地的仓库路径下运行这个:

1
2
3
4
# svn co --username tom --password 123456 http://my-project.googlecode.com/svn/  code
# cd code
# svn log --xml | grep author | sort -u | perl -pe 's/.*>(.*?)<.*/$1 = /' > /root/users.txt

这会将日志输出为 XML 格式,然后保留作者信息行、去除重复、去除 XML 标记。 然后,将输出重定向到你的 users.txt 文件中,这样就可以在每一个记录后面加入对应的 Git 用户数据,修改users.txt文件满足以下的格式:

1
2
3
4
# vim /root/users.txt
schacon = schacon <schacon@geemail.com>
selse = selse <selse@geemail.com>

然后开始把SVN仓库转变成Git仓库,执行以下命令:

1
2
# git svn clone http://my-project.googlecode.com/svn/   --authors-file=/root/users.txt  --no-metadata  my_project

为了将标签变为合适的 Git 标签,运行

1
2
3
4
# cd  my_project
# cp -Rf .git/refs/remotes/origin/tags/* .git/refs/tags/
# rm -Rf .git/refs/remotes/origin/tags

这会使原来在 remotes/origin/tags/ 里的远程分支引用变成真正的(轻量)标签。

接下来,将 refs/remotes 下剩余的引用移动为本地分支:

1
2
3
# cp -Rf .git/refs/remotes/* .git/refs/heads/
# rm -Rf .git/refs/remotes

现在所有的旧分支都是真正的 Git 分支,并且所有的旧标签都是真正的 Git 标签。 最后一件要做的事情是,将你的新 Git 服务器添加为远程仓库并推送到上面。 下面是一个将你的服务器添加为远程仓库的例子:

1
2
# git remote add origin git@my-git-server:myrepository.git

因为想要上传所有分支与标签,你现在可以运行:

1
2
$ git push origin --all

通过以上漂亮、干净地导入操作,你的所有分支与标签都应该在新 Git 服务器上,你可以去gitlab上查看结果了。

参考资料: https://blog.csdn.net/ouyang_peng/article/category/1590137

转自:http://www.html-js.com/article/1628

一个Demo Gihub:https://github.com/sjzlei1989/Bezier-csharp

相信很多同学都知道“贝塞尔曲线”这个词,我们在很多地方都能经常看到。但是,可能并不是每位同学都清楚地知道,到底什么是“贝塞尔曲线”,又是什么特点让它有这么高的知名度。

贝塞尔曲线的数学基础是早在 1912 年就广为人知的伯恩斯坦多项式。但直到 1959 年,当时就职于雪铁龙的法国数学家 Paul de Casteljau 才开始对它进行图形化应用的尝试,并提出了一种数值稳定的 [de Casteljau 算法](http://en.wikipedia.org/wiki/De_Casteljau' rel=)。然而贝塞尔曲线的得名,却是由于 1962 年另一位就职于雷诺的法国工程师 Pierre Bézier 的广泛宣传。他使用这种只需要很少的控制点就能够生成复杂平滑曲线的方法,来辅助汽车车体的工业设计。

正是因为控制简便却具有极强的描述能力,贝塞尔曲线在工业设计领域迅速得到了广泛的应用。不仅如此,在计算机图形学领域,尤其是矢量图形学,贝塞尔曲线也占有重要的地位。今天我们最常见的一些矢量绘图软件,如 Flash、Illustrator、CorelDraw 等,无一例外都提供了绘制贝塞尔曲线的功能。甚至像 Photoshop 这样的位图编辑软件,也把贝塞尔曲线作为仅有的矢量绘制工具(钢笔工具)包含其中。

贝塞尔曲线在 web 开发领域同样占有一席之地。CSS3 新增了 transition-timing-function 属性,它的取值就可以设置为一个三次贝塞尔曲线方程。在此之前,也有不少 JavaScript 动画库使用贝塞尔曲线来实现美观逼真的缓动效果。

下面我们就通过例子来了解一下如何用 de Casteljau 算法绘制一条贝塞尔曲线。

在平面内任选 3 个不共线的点,依次用线段连接。enter image description here

在第一条线段上任选一个点 D。计算该点到线段起点的距离 AD,与该线段总长 AB 的比例。enter image description here

根据上一步得到的比例,从第二条线段上找出对应的点 E,使得 AD:AB = BE:BCenter image description here

连接这两点 DE。enter image description here

从新的线段 DE 上再次找出相同比例的点 F,使得 DF:DE = AD:AB = BE:BCenter image description here

到这里,我们就确定了贝塞尔曲线上的一个点 F。接下来,请稍微回想一下中学所学的极限知识,让选取的点 D 在第一条线段上从起点 A 移动到终点 B,找出所有的贝塞尔曲线上的点 F。所有的点找出来之后,我们也得到了这条贝塞尔曲线。enter image description here

如果你实在想象不出这个过程,没关系,看动画!enter image description here

回过头来看这条贝塞尔曲线,为了确定曲线上的一个点,需要进行两轮取点的操作,因此我们称得到的贝塞尔曲线为二次曲线(这样记忆很直观,但曲线的次数其实是由前面提到的伯恩斯坦多项式决定的)。

当控制点个数为 4 时,情况是怎样的?enter image description here

步骤都是相同的,只不过我们每确定一个贝塞尔曲线上的点,要进行三轮取点操作。如图, AE:AB = BF:BC = CG:CD = EH:EF = FI:FG = HJ:HI ,其中点 J 就是最终得到的贝塞尔曲线上的一个点。enter image description here

这样我们得到的是一条三次贝塞尔曲线。enter image description here

看过了二次和三次曲线,更高次的贝塞尔曲线大家应该也知道要怎么画了吧。那么比二次曲线更简单的一次(线性)贝塞尔曲线存在吗?长什么样?根据前面的介绍,只要稍作思考,想必你也能猜出来了。哈!就是一条直线~enter image description here

能画曲线也能画直线,是不是很厉害?要绘制更复杂的曲线,控制点的增加也仅仅是线性的。这一特点使其不光在工业设计领域大展拳脚,就连数学基础不好的人也可以比较容易地掌握,比如大多数平面美术设计师们。enter image description here

上面介绍的内容并不足以展示贝塞尔曲线的真正威力。推广到三维空间的贝塞尔曲面,以及更进一步的非均匀有理 B 样条(NURBS),早已成为当今计算机辅助设计(CAD)的行业标准,不论是我们平常用到的各种产品,还是在电影院看到的精彩大片,都少不了它们的功劳。enter image description here

enter image description here

动态绘制贝塞尔曲线的在线演示

作者:jesseyoung
来源:CSDN
原文:https://blog.csdn.net/JesseYoung/article/details/35257527
版权声明:本文为博主原创文章,转载请附上博文链接!

1 事件简介

事件(event)是MySQL在相应的时刻调用的过程式数据库对象。一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的“事件调度器”。

事件和触发器类似,都是在某些事情发生的时候启动。当数据库上启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于他们彼此相似,所以事件也称为临时性触发器。

事件取代了原先只能由操作系统的计划任务来执行的工作,而且MySQL的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精确到每分钟执行一次。

2 事件的优缺点
2.1 优点

一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能。

可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用了。

2.2 缺点
定时触发,不可以调用。

3 创建事件

一条create event语句创建一个事件。每个事件由两个主要部分组成,第一部分是事件调度(event schedule),表示事件何时启动以及按什么频率启动,第二部分是事件动作(event action ),这是事件启动时执行的代码,事件的动作包含一条SQL语句,它可能是一个简单地insert或者update语句,也可以使一个存储过程或者benin…end语句块,这两种情况允许我们执行多条SQL。

一个事件可以是活动(打开)的或停止(关闭)的,活动意味着事件调度器检查事件动作是否必须调用,停止意味着事件的声明存储在目录中,但调度器不会检查它是否应该调用。在一个事件创建之后,它立即变为活动的,一个活动的事件可以执行一次或者多次。

3.1 创建语法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE
    [DEFINER = { user | CURRENT_USER }]
    EVENT
    [IF NOT EXISTS]
    event_name
    ON SCHEDULE schedule
    [ON COMPLETION [NOT] PRESERVE]
    [ENABLE | DISABLE | DISABLE ON SLAVE]
    [COMMENT 'comment']
    DO event_body;
 
schedule:
    AT timestamp [+ INTERVAL interval] ...
  | EVERY interval
    [STARTS timestamp [+ INTERVAL interval] ...]
    [ENDS timestamp [+ INTERVAL interval] ...]
 
interval:
    quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
              WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
              DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

名词解释:

event_name :创建的event名字(唯一确定的)。
ON SCHEDULE:计划任务。
schedule: 决定event的执行时间和频率(注意时间一定要是将来的时间,过去的时间会出错),有两种形式 AT和EVERY。
[ON COMPLETION [NOT] PRESERVE]: 可选项,默认是ON COMPLETION NOT PRESERVE 即计划任务执行完毕后自动drop该事件;ON COMPLETION PRESERVE则不会drop掉。
[COMMENT ‘comment’] :可选项,comment 用来描述event;相当注释,最大长度64个字节。
[ENABLE | DISABLE] :设定event的状态,默认ENABLE:表示系统尝试执行这个事件, DISABLE:关闭该事情,可以用alter修改
DO event_body: 需要执行的sql语句(可以是复合语句)。CREATE EVENT在存储过程中使用时合法的。

3.2 开启关闭事件调度器

3.2.1 MySQL事件调度器event_scheduler负责调用事件,它默认是关闭的。这个调度器不断地监视一个事件是否要调用, 要创建事件,必须打开调度器。

1
2
3
4
5
6
mysql> show variables like '%event_scheduler%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | OFF   |
+-----------------+-------+

3.2.2 开启事件调度器
通过命令行

可通过如下任何一个命令行

1
2
3
4
SET GLOBAL event_scheduler = ON;
SET @@global.event_scheduler = ON;
SET GLOBAL event_scheduler = 1;
SET @@global.event_scheduler = 1;

通过配置文件my.cnf

1
event_scheduler = 1 #或者ON

查看调度器线程

1
2
3
4
5
6
7
mysql> show processlist;
+----+-----------------+-----------+------+---------+------+------------------------+------------------+
| Id | User            | Host      | db   | Command | Time | State                  | Info             |
+----+-----------------+-----------+------+---------+------+------------------------+------------------+
|  2 | root            | localhost | NULL | Query   |    0 | NULL                   | show processlist |
|  3 | event_scheduler | localhost | NULL | Daemon  |    6 | Waiting on empty queue | NULL             |
+----+-----------------+-----------+------+---------+------+------------------------+------------------+

3.2.3 关闭事件调度器

通过命令行

可通过如下任何一个命令行

1
2
3
4
SET GLOBAL event_scheduler = OFF;
SET @@global.event_scheduler = OFF;
SET GLOBAL event_scheduler = 0;
SET @@global.event_scheduler = 0;

通过配置文件my.cnf

在[mysqld]下增加

1
event_scheduler = 0 #或者OFF,DISABLED

查看调度器线程

1
2
3
4
5
6
mysql> show processlist;
+----+------+-----------+------+---------+------+-------+------------------+
| Id | User | Host      | db   | Command | Time | State | Info             |
+----+------+-----------+------+---------+------+-------+------------------+
|  2 | root | localhost | NULL | Query   |    0 | NULL  | show processlist |
+----+------+-----------+------+---------+------+-------+------------------+

3.3 例如:创建一个表记录每次事件调度的名字和事件戳

3.3.1 创建测试表

1
2
mysql> drop table if exists events_list;
mysql> create table events_list(event_name varchar(20) not null, event_started timestamp not null);

3.3.2 创建事件1(立即启动事件)

1
2
3
4
create event event_now 
on schedule 
at now() 
do insert into events_list values('event_now', now());

查看事件执行结果

1
2
3
4
5
6
mysql> select * from events_list;
+------------+---------------------+
| event_name | event_started       |
+------------+---------------------+
| event_now  | 2014-07-01 04:06:40 |
+------------+---------------------+

3.3.3 创建事件2(每分钟启动事件)

1
2
3
4
create event test.event_minute 
on schedule 
every  1 minute  
do insert into events_list values('event_now', now());

查看事件执行结果

1
2
3
4
5
6
7
8
mysql> select * from events_list;
+------------+---------------------+
| event_name | event_started       |
+------------+---------------------+
| event_now  | 2014-07-01 04:26:53 |
| event_now  | 2014-07-01 04:27:53 |
| event_now  | 2014-07-01 04:28:53 |
+------------+---------------------+

3.4 注意:

默认创建事件存储在当前库中,也可显示指定事件创建在哪个库中

通过show events只能查看当前库中创建的事件

事件执行完即释放,如立即执行事件,执行完后,事件便自动删除,多次调用事件或等待执行事件可以查看到。

如果两个事件需要在同一时刻调用,mysql会确定调用他们的顺序,如果要指定顺序,需要确保一个事件至少在另一个事件1秒后执行

对于递归调度的事件,结束日期不能在开始日期之前。

select可以包含在一个事件中,然而他的结果消失了,就好像没执行过。

4 查看事件

查看当前所在库的事件

1
mysql> show events;

查看所有事件

1
mysql> select * from mysql.event;

5 修改事件

一条alter event语句可以修改事件的定义和属性。我们可以让一个事件成为停止的或者再次让它活动,也可以修改一个事件的名字或者整个调度。然而当一个使用 ON COMPLETION NOT PRESERVE 属性定义的事件最后一次执行后,事件直接就不存在了,不能修改。

5.1 语法如下:

1
2
3
4
5
6
7
8
9
ALTER
    [DEFINER = { user | CURRENT_USER }]
    EVENT event_name
    [ON SCHEDULE schedule]
    [ON COMPLETION [NOT] PRESERVE]
    [RENAME TO new_event_name]
    [ENABLE | DISABLE | DISABLE ON SLAVE]
    [COMMENT 'comment']
    [DO event_body]

5.2 例如

修改上面例子3.3.3 每分钟启动事件为每30秒启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
alter event test.event_minute
on schedule 
every  30 second  
do insert into events_list values('event_now', now());
    修改上面例子3.3.3 事件名字为event_second


alter event test.event_minute 
rename to test.event_second;
    修改上面例子3.3.3 事件为不活动和再次活动


alter event test.event_second disable;
alter event test.event_second enable;

6 删除事件

如果一个事件不再需要,我们可以使用一条drop event 语句删除它。使用这条语句我们不需要等到最后一次事件调用。

6.1 基本语法

1
DROP EVENT [IF EXISTS] event_name

6.2 例如

1
drop event if exists event_second;

7 事件和权限

8 更多详细案例