log4life

应无所住而生其心

凡所有相,皆是虚妄。若见诸相非相,即见如来



最近更新

日志列表

打车抬表费用计算

发布者:刘金雨,发布时间:‎‎2009-7-4 下午2:32‎‎   [ 更新时间:‎‎2009-7-4 下午3:00‎‎ ]

 
<html>
<script type="text/javascript" src="wz_jsgraphics.js"></script>

<body>
<script type="text/javascript">
<!--
function getPrice(distance, night) {
 var unitPrice = 2.0,
  basicDistance = 3,
  basicPrice = 10,
  extDistance = 15,
  extPrice = 3.0;
 
 var price = 0.0;
 if ( distance == 0 ) return 0;
 if ( distance <= basicDistance ) return basicPrice;
  
 if ( distance <= extDistance ) {
  price = basicPrice + unitPrice * (distance - basicDistance);
  return price;
 }
 
 price += basicPrice + unitPrice*(extDistance-basicDistance) + extPrice*(distance-extDistance)
 return price;
}

function getPriceWithReset(distance, night, reset) {
 if ( reset == 0 ) {
  return getPrice(distance, night);
 } else {
  return getPrice(reset, night) * Math.floor(distance/reset) + getPrice(distance % reset, night);
 }
}

var coordXUnit = 8, coordYUnit = 3,
 basicX = 100, basicY = 50,
 coordMaxX = 101, coordMaxY = 251;

function drawString(str, x, y) {
 jg.drawString(str, basicX+x*coordXUnit, basicY+(coordMaxY-y)*coordYUnit);
}
 
function drawPoint(x, y) {
 drawLine(x, y, x, y);
}

function drawLine(x1, y1, x2, y2) {
 jg.drawLine(basicX + x1*coordXUnit, basicY + (coordMaxY-y1)*coordYUnit, basicX + x2*coordXUnit, basicY + (coordMaxY-y2)*coordYUnit);
}

function drawPolyline(ax, ay) {
 var axx = new Array(), ayy = new Array();

 for (var e in ax) {
  axx.push(basicX + (ax[e] * coordXUnit) );
 }

 for (var e in ay) {
  ayy.push(basicY + (coordMaxY - ay[e])*coordYUnit);
 }

 jg.drawPolyline(axx, ayy);
}
  
function drawCoordinate() {
 jg.setColor("#ee8800");
 drawLine(0, 0, coordMaxX, 0);
 drawLine(0, 0, 0, coordMaxY);
 
 drawString(0, -2, -2);
 for (var i = 1; i < coordMaxX; i++) {
  if (i%5==0) {
   // draw grid
   jg.setStroke(Stroke.DOTTED);
   drawLine(i, 0, i, coordMaxY);
   // draw mark
   jg.setStroke(0);
   drawLine(i, 0, i, -2);
   drawString(i, i-1, -3);
  } else {
   drawLine(i, 0, i, -1);
  }
 }
 
 for (var i = 1; i < coordMaxY ; i++) {
  if (i%5==0) {
   // draw grid
   jg.setStroke(Stroke.DOTTED);
   drawLine(0, i, coordMaxX, i);
   // draw mark
   jg.setStroke(0);
   drawLine(0, i, -2, i);
   drawString(i, -7, i+1);
  } else {
   drawLine(0, i, -1, i);
  }
 }
}

function drawPriceLine(night, reset) {
 var ax = new Array(), ay = new Array();
 
 for (var d=0; d<70; d++) {
  ax.push(d);
  ay.push(getPriceWithReset(d, 0, reset));
 }
 drawPolyline(ax, ay);
}

/////////////// main section ///////////////
var jg = new jsGraphics();
jg.setFont("verdana,geneva,sans-serif", "10px", Font.PLAIN);


drawCoordinate();
drawString("reset:", 0, -10);
jg.setColor("#000000");
drawPriceLine(0, 0);
drawString("0", 5, -10);
jg.setColor("#FF0000");
drawPriceLine(0, 10);
drawString("10", 10, -10);
jg.setColor("#00FF00");
drawPriceLine(0, 15);
drawString("15", 15, -10);
jg.setColor("#0000FF");
drawPriceLine(0, 20);
drawString("20", 20, -10);

///////////////// from wangjing to my home, 35KM /////////////////
jg.setColor("#880000");
var xp = new Array(), yp = new Array();
for ( var i=10; i<30; i++) {
 xp.push(i);
 yp.push(getPriceWithReset(35, 0, i));
}
drawPolyline(xp, yp);

drawString(getPriceWithReset(35, 0, 15), 0, -20);
jg.paint();
//-->
</script>
</body>
</html>

Android Build Error list

发布者:刘金雨,发布时间:‎‎2009-2-26 上午2:20‎

android "make: *** No rule to make target" 'jdk/lib/tools.jar' needed by `out/target/common/docs/offline-sdk-timestamp'.  Stop.
一般来说是Java的环境变量设置的问题,需要设置JAVA_HOME变量到JDK的目录下。

为什么cpio比tar要好

发布者:刘金雨,发布时间:‎‎2009-2-9 下午3:20‎

为什么cpio比tar好?有这样几个原因。
1、cpio会保留硬连接(hard link),备份的时候这个很重要
2、cpio没有文件名长度的限制。确实,guntar在这一点上做过改进,允许使用长文件名(实际上是创建了一个临时文件用来保存实际的文件名),但是在非gnu的tar工具上仍然存在这个问题。
3、默认情况下,cpio保留时间戳
4、在编写脚本的时候,cpio可以更好的控制要操作哪些文件。因为cpio需要显式的制定要操作的文件列表,例如下面哪个更加容易理解?
find . -type f -name '*.sh' -print | cpio -o | gzip >sh.cpio.gz

或者在Solaris上:
find . -type f -name '*.sh' -print >/tmp/includeme
tar -cf - . -I /tmp/includeme | gzip >sh.tar.gz

或者用gnutar:
find . -type f -name '*.sh' -print >/tmp/includeme
tar -cf - . --files-from=/tmp/includeme | gzip >sh.tar.gz

这儿有一个需要特别注意的:对于包含大量文件的列表,不能将find放在反引号(`)内,因为命令行长度会超出长度限制,因此必须使用中间文件。find和tar分开跑很明显会使得速度减慢。

下面这个例子更加复杂,将一部分文件打包到一个文件中,其它部分打包到另外一个文件中:

find . -depth -print >/tmp/files
egrep    '\.sh$' /tmp/files | cpio -o | gzip >with.cpio.gz
egrep -v '\.sh$' /tmp/files | cpio -o | gzip >without.cpio.gz


在 Solaris 下:
find . -depth -print >/tmp/files
egrep    '\.sh$' /tmp/files >/tmp/with
tar -cf - . -I /tmp/with    | gzip >with.tar.gz
tar -cf - .    /tmp/without | gzip >without.tar.gz

使用 gnutar:
find . -depth -print >/tmp/files
egrep    '\.sh$' /tmp/files >/tmp/with
tar -cf - . -I /tmp/with    | gzip >with.tar.gz
tar -cf - . -X /tmp/without | gzip >without.tar.gz

同样的,find和tar分开跑会使得速度变慢。创建多个中间文件也搞出了更多的混乱。gnutar稍好些,但是命令行参数却是不兼容的。

5、如果有很多文件需要通过网络在两台机器之间复制,则可以并行的跑几个cpio。例如:

find . -depth -print >/tmp/files
split /tmp/files
for F in /tmp/files?? ; do
 cat $F | cpio -o | ssh destination "cd /target && cpio -idum" &
 done

注意,如果能够将输入平均分成几个部分来进行并行处理会更好。

Android源码构建工具速览(二)—— 清单文件

发布者:刘金雨,发布时间:‎‎2009-1-10 下午1:21‎‎   [ 更新时间:‎‎2009-1-10 下午1:22‎‎ ]

 上回已经简单的在本地构造了一个Android的源码库,这回来看看这个源码库是如何构造出来的。

 

这一切其实都是基于那个名为repo的构造工具。回到最开始的命令 $ curl http://android.git.kernel.org/repo > ~/bin/repo
这个命令从网站上下载了一个名为repo的脚本,它实际上是段python的代码,这个代码仔细看看还是有点意思的。它其实是整个构建工具的一小部分代码,而这一小部分的代码的功能主要就是去下载自身其它的代码,并初始化构建环境。


在运行这个工具的时候,它首先会去检查当前目录下的.repo目录,然后从脚本内置的(或命令行指定的)一个地址 git://android.kernel.org/tools/repo.git 去使用git clone一份最新的repo工具的完整的版本库放置到 .repo/repo 目录下,之后checkout出最新的代码。这些代码就是repo的其它部分的代码。这其中的 main.py 就是repo构建工具的主干入口代码。

 

而在之前的构造过程中的调用命令 $ repo init -u git://android.git.kernel.org/platform/manifest.git 中,repo首先完成了前面所说的对自身的更新和初始化,然后通过调用后面补充进来的代码完成init的操作。在这个操作中, repo从 git://android.git.kernel.org/platform/manifest.git 这个地址下载了一份整个源码仓库的清单的版本库,并checkout出一份最新的清单,即 .repo/manifests/default.xml 文件。该文件是一个xml文件,在这个文件中描述了获取代码的远程版本库地址、其中所涉及到的每个项目的地址等等。下面是其中一部分:

  1. <manifest branch="master">
  2.   <remote  name="korg"
  3.            fetch="git://android.git.kernel.org/"
  4.            review="review.source.android.com" />
  5.      
  6.   <project path="bionic" name="platform/bionic" />
  7.   
  8.   <project path="external/clearsilver" name="platform/external/clearsilver">
  9.     <import>
  10.       <remap strip="clearsilver-%version%/" />
  11.       <mirror url="http://android.git.kernel.org/pub/clearsilver-%version%.tar.gz" />
  12.       <snapshot version="0.10.5" check="ec5fff5d7367ddd29a619cf81ae264687fde94c8" />
  13.     </import>
  14.   </project>
  15.   
  16.   ... ...
  17.   
  18. </manifest>

这里只是截取了其中一小部分的片段用来说明问题。

remote节点的fetch属性描述了远程的版本库的基本地址,之后是一系列的project节点。每一个project节点都有一个path和name属性,path是该项目在本地的存储地址,如bionic则是存储在本地的 ./repo/projects/bionic 下面,而name属性是远程版本库中的路径,与remote的fetch的地址结合起来即可得到该项目的版本库地址,如bionic的版本库是在 git://android.git.kernel.org/platform/bionic


而有的project定义中有import节点,该import节点中定义的一般都是该项目所依赖的第三方的独立项目,这些项目是没有历史版本信息的,因此只是一个tar.gz的包。repo在同步的过程中会将其下载下来,解压、加入到该项目的版本库中,并打上一个tag标记。

通过这个清单文件,repo可以实现整个源码库的随时更新和同步,这也是基于git的版本控制的特性所带来的独特的优势。

Android源码构建工具速览(一)——构造源码库

发布者:刘金雨,发布时间:‎‎2009-1-10 下午12:57‎‎   [ 更新时间:‎‎2009-1-10 下午1:21‎‎ ]

随着第一款Android的手机上市,Google也终于发布了其Android的源码。通常情况下,一个开源项目的发布都是伴随着一个巨大的完整的xxx-src.tar.gz的源码包,然后解压、configure/make即可。而Android是基于传说中的Git来管理的,在发布方面自然也有所不同,它基于Git构造了一个可以随时同步更新的源码库。

http://source.android.com/download 可以找到一段简单的下载源码的介绍。大致情况是,首先要在Linux或者MacO的系统下操作,其次要保证Git的版本在1.5.4之上,Python的版本在2.4之上。

先做一个小准备,在个人home目录下建立一个bin目录,并加入到PATH环境变量中
$ mkdir ~/bin
$ export PATH=$HOME/bin:$PATH

要下载其源码,先要安装一个Android的构建工具 repo。
$ curl http://android.git.kernel.org/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

然后再建立一个存放源码的目录
$ mkdir ~/android ; cd ~/android

之后使用这个repo工具,来初始化这个源码仓库:
$ repo init -u git://android.git.kernel.org/platform/manifest.git

片刻等待之后,仓库初始化完成。此时,这个仓库只是更新了repo这个构建工具本身,并下载了整个Android源码仓库的一个清单的版本库,在~/android/.repo下面能够看到这些文件。其中 ~/android/.repo/repo 目录是构建工具的全部代码,基于Python写成,稍后再看。 其次是 ~/android/.repo/manifests/default.xml文件,这个是整个Android源码库的清单文件,之后repo这个工具会根据这个清单依次下载所有的代码。而~/android/.repo/manifest.git则是这个清单文件的版本库 :) 。

Git有一个有意思的特性,就是可以制定存放版本库版本信息的目录的位置,因而可以将存放版本信息的目录和实际的项目文件放置于不同的目录下,而不是像以前的cvs或者Subversion一样在每一个目录下都有一个讨厌的.xxx隐藏目录。这也从某种程度上减少了冗余信息。

经过上述步骤之后,可以开始进行源码仓库的下载了,对于repo来说,称之为“同步”——sync。

$ repo sync

下载过程中随时可以终断,中断后重新执行同步即可更新到最新的源码仓库。

 

‹ 上一页    1-5/5    下一页 ›