lucene.net源码学习笔记(一)

今天开始看lucene.net源码,首先是挑了一个比较简单的类DateField来看了一下。

DateField类提供了一些日期字符串与日期时间之间互相转换的静态方法。

在lucene.net中日期字符串实际是就是一个36进制(刚好所有的数字,字母能够用上)的字符串,由0-9,a-z这些字符组成,他们之间的转换如下:

日期时间 = (日期字符串的36进制值) * 1毫秒 + (1970年1月1日)

在lucene中最小的时间为1970年1月1日,实在是不明白为什么1970年,难道作者那年出生?

下面是我对源码的一些分析。

 

ExpandedBlockStart.gif ContractedBlock.gif /**/ /*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 * 
http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 
*/


using  System;
using  PrefixQuery  =  Lucene.Net.Search.PrefixQuery;
using  RangeQuery  =  Lucene.Net.Search.RangeQuery;

namespace  Lucene.Net.Documents
ExpandedBlockStart.gifContractedBlock.gif
{
    
// for javadoc

ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary> Provides support for converting dates to strings and vice-versa.
    
/// The strings are structured so that lexicographic sorting orders by date,
    
/// which makes them suitable for use as field values and search terms.
    
/// 
    
/// <P>Note that this class saves dates with millisecond granularity,
    
/// which is bad for {@link RangeQuery} and {@link PrefixQuery}, as those
    
/// queries are expanded to a BooleanQuery with a potentially large number
    
/// of terms when searching. Thus you might want to use
    
/// {@link DateTools} instead.
    
/// 
    
/// <P>
    
/// Note: dates before 1970 cannot be used, and therefore cannot be
    
/// indexed when using this class. See {@link DateTools} for an
    
/// alternative without such a limitation.
    
/// 
    
/// </summary>
    
/// <deprecated> If you build a new index, use {@link DateTools} instead. This class is included for use with existing
    
/// indices and will be removed in a future release.
    
/// </deprecated>

    public class DateField
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
//私有的构造函数,由于该类只是提供一些静态方法,因此无需被实例化
        private DateField()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
        }

        
        
// 计算表示日期字符串的长度,该字符串长度必须能够足够表示1000年,1000L(年)*365(天)*24(小时)*60(分)*60(秒)*1000(毫秒),365天?润年的那一天被吃掉了
        
// 将计算的最大时间值转换为16进制表示字符串,不过觉得这个16应该是错的,正确的应该是36进制
        
// 后来在网上查到发现有的版本是System.Convert.ToString( 1000L * 365 * 24 * 60 * 60 * 1000, 36 ).Length,这个也是错的
        
// System.Convert.ToString函数的第二参数只能是2,8,10,16,如果是36会抛出异常
        
// 我想正确的的两个写法应该是:
        
// (1)SupportClass.Number.ToString(1000L * 365 * 24 * 60 * 60 * 1000, 36).Length
        
// (2)System.Convert.ToString( 1000L * 365 * 24 * 60 * 60 * 1000, 16 ).Length
        
// make date strings long enough to last a millenium
        private static int DATE_LEN = SupportClass.Number.ToString(
            
1000L * 365 * 24 * 60 * 60 * 100016).Length;
        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 表示最小时间的字符串"0000."
        
/// </summary>
        
/// <returns></returns>

        public static System.String MIN_DATE_STRING()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
return TimeToString(0);
        }

        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 表示最大时间的字符串"ZZZZ."
        
/// </summary>
        
/// <returns></returns>

        public static System.String MAX_DATE_STRING()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
char[] buffer = new char[DATE_LEN];
            
// 36进制最大的数字为'Z'(35),ForDigit第一个为什么是36-1而不是SupportClass.Character.MAX_RADIX-1,代码风格有点怪异
            char c = SupportClass.Character.ForDigit(36 - 1, SupportClass.Character.MAX_RADIX);
            
for (int i = 0; i < DATE_LEN; i++)
                buffer[i] 
= c;
            
return new System.String(buffer);
        }

        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary> 
        
/// Converts a Date to a string suitable for indexing.
        
/// 日期转字符串
        
/// </summary>
        
/// <throws>  RuntimeException if the date specified in the </throws>
        
/// <summary> method argument is before 1970
        
/// </summary>

        public static System.String DateToString(System.DateTime date)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
// 计算转换时间与最小时间的时间间隔,最小时间为1970年1月1号,为什么是1970年,难道原作者那年出生?这个时间我想改为1900也应该没什么问题。
            TimeSpan ts = date.Subtract(new DateTime(197011));
            
// 减去由于时区造成的时间偏移量
            ts = ts.Subtract(TimeZone.CurrentTimeZone.GetUtcOffset(date));
            
return TimeToString(ts.Ticks / TimeSpan.TicksPerMillisecond);
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary> 
        
/// Converts a millisecond time to a string suitable for indexing.
        
/// 该函数实际上就是将长整型数值time转换成36进制的字符串,如果长度不足DATE_LEN则在前面补0,补0也是为了方便时间的排序功能
        
/// </summary>
        
/// <throws>  RuntimeException if the time specified in the </throws>
        
/// <summary> method argument is negative, that is, before 1970
        
/// </summary>

        public static System.String TimeToString(long time)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
// 若时间必须小于1970年则抛出异常 
            if (time < 0)
                
throw new System.SystemException("time '" + time + "' is too early, must be >= 0");
            
            System.String s 
= SupportClass.Number.ToString(time, SupportClass.Number.MAX_RADIX);
            
            
// 若超出长度为DATE_LE的字符串所能表示的最大时间值则抛出异常
            if (s.Length > DATE_LEN)
                
throw new System.SystemException("time '" + time + "' is too late, length of string " + "representation must be <= " + DATE_LEN);
            
            
// 长度不足DATE_LEN则在前面补0
            
// Pad with leading zeros
            if (s.Length < DATE_LEN)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                System.Text.StringBuilder sb 
= new System.Text.StringBuilder(s);
                
while (sb.Length < DATE_LEN)
                    sb.Insert(
00);
                s 
= sb.ToString();
            }

            
            
return s;
        }

        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// Converts a string-encoded date into a millisecond time. 
        
/// 该函数实际就是将36进制字符串转换成长整型数值
        
/// </summary>

        public static long StringToTime(System.String s)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
return SupportClass.Number.Parse(s, SupportClass.Number.MAX_RADIX);
        }

        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// Converts a string-encoded date into a Date object. 
        
/// 日期字符串转日期类型
        
/// </summary>

        public static System.DateTime StringToDate(System.String s)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
long ticks = StringToTime(s) * TimeSpan.TicksPerMillisecond;
            System.DateTime date 
= new System.DateTime(197011);
            date 
= date.AddTicks(ticks);
            date 
= date.Add(TimeZone.CurrentTimeZone.GetUtcOffset(date));
            
return date;
        }

    }

}

 

终于弄完了,困死了,睡觉去...zzzZZZ

转载于:https://www.cnblogs.com/laizhenyuan/archive/2009/02/23/1396206.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值