⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsdirectory.cpp

📁 clucene是c++版的全文检索引擎,完全移植于lucene,采用 stl 编写.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    
    struct dirent* fl = readdir(dir);
    struct fileStat buf;
    AStringArray names;

    char path[CL_MAX_DIR];
	strncpy(path,directory,CL_MAX_DIR);
    strcat(path,PATH_DELIMITERA);
    char* pathP = path + strlen(path);

    while ( fl != NULL ){
      strcpy(pathP,fl->d_name);
      fileStat(path,&buf);
      if ( !(buf.st_mode & S_IFDIR) ) {
        names.push_back( STRDUP_AtoA(fl->d_name) );
      }
      fl = readdir(dir);
    }
    closedir(dir);

    size_t size = names.size();
    char** ret = _CL_NEWARRAY(char*,size+1);
    for ( size_t i=0;i<size;i++ )
      ret[i] = names[i];
    ret[size]=NULL;
    return ret;
  }

  bool FSDirectory::fileExists(const char* name) const {
	  CND_PRECONDITION(directory[0]!=0,"directory is not open");
    char fl[CL_MAX_DIR];
    priv_getFN(fl, name);
    return Misc::dir_Exists( fl );
  }

  const char* FSDirectory::getDirName() const{
    return directory;
  }

  //static
  FSDirectory* FSDirectory::getDirectory(const char* file, const bool _create){
    FSDirectory* dir = NULL;
	{
		if ( !file || !*file )
			_CLTHROWA(CL_ERR_IO,"Invalid directory");

		SCOPED_LOCK_MUTEX(DIRECTORIES.THIS_LOCK)
		dir = DIRECTORIES.get(file);
		if ( dir == NULL  ){
			dir = _CLNEW FSDirectory(file,_create);
			DIRECTORIES.put( dir->directory, dir);
		}else if ( _create ){
	    	dir->create();
		}
	}

	{
		SCOPED_LOCK_MUTEX(dir->THIS_LOCK)
		dir->refCount++;
	}

    return _CL_POINTER(dir);
  }

  int64_t FSDirectory::fileModified(const char* name) const {
	CND_PRECONDITION(directory[0]!=0,"directory is not open");
    struct fileStat buf;
    char buffer[CL_MAX_DIR];
    priv_getFN(buffer,name);
    if (fileStat( buffer, &buf ) == -1 )
      return 0;
    else
      return buf.st_mtime;
  }

  //static
  int64_t FSDirectory::fileModified(const char* dir, const char* name){
    struct fileStat buf;
    char buffer[CL_MAX_DIR];
	_snprintf(buffer,CL_MAX_DIR,"%s%s%s",dir,PATH_DELIMITERA,name);
    fileStat( buffer, &buf );
    return buf.st_mtime;
  }

  void FSDirectory::touchFile(const char* name){
	  CND_PRECONDITION(directory[0]!=0,"directory is not open");
    char buffer[CL_MAX_DIR];
    _snprintf(buffer,CL_MAX_DIR,"%s%s%s",directory,PATH_DELIMITERA,name);
	
	//todo: haven't checked this:
    int32_t r = _open(buffer, O_RDWR, _S_IWRITE);
	if ( r < 0 )
		_CLTHROWA(CL_ERR_IO,"IO Error while touching file");
	_close(r);
  }

  int64_t FSDirectory::fileLength(const char* name) const {
	  CND_PRECONDITION(directory[0]!=0,"directory is not open");
    struct fileStat buf;
    char buffer[CL_MAX_DIR];
    priv_getFN(buffer,name);
    if ( fileStat( buffer, &buf ) == -1 )
      return 0;
    else
      return buf.st_size;
  }

  IndexInput* FSDirectory::openInput(const char* name ) {
  	return openInput(name, LUCENE_STREAM_BUFFER_SIZE);
  }
  
#ifdef LUCENE_FS_MMAP
  IndexInput* FSDirectory::openMMapFile(const char* name, int32_t bufferSize){
    char fl[CL_MAX_DIR];
    priv_getFN(fl, name);
	if ( Misc::file_Size(fl) < LUCENE_INT32_MAX_SHOULDBE ) //todo: would this be bigger on 64bit systems?. i suppose it would be...test first
		return _CLNEW MMapIndexInput( fl );
	else
		return _CLNEW FSIndexInput( fl, bufferSize );
  }
#endif

  IndexInput* FSDirectory::openInput(const char* name, int32_t bufferSize ){
	CND_PRECONDITION(directory[0]!=0,"directory is not open")
    char fl[CL_MAX_DIR];
    priv_getFN(fl, name);
#ifdef LUCENE_FS_MMAP
	//todo: do some tests here... like if the file
	//is >2gb, then some system cannot mmap the file
	//also some file systems mmap will fail?? could detect here too
	if ( useMMap && Misc::file_Size(fl) < LUCENE_INT32_MAX_SHOULDBE ) //todo: would this be bigger on 64bit systems?. i suppose it would be...test first
		return _CLNEW MMapIndexInput( fl );
	else
#endif
	return _CLNEW FSIndexInput( fl, bufferSize );
  }
		
  void FSDirectory::close(){
      SCOPED_LOCK_MUTEX(DIRECTORIES.THIS_LOCK)
      {
	      SCOPED_LOCK_MUTEX(THIS_LOCK)

	      CND_PRECONDITION(directory[0]!=0,"directory is not open");

          if (--refCount <= 0 ) {//refcount starts at 1
              Directory* dir = DIRECTORIES.get(getDirName());
              if(dir){
                DIRECTORIES.remove( getDirName() ); //this will be removed in ~FSDirectory
			    _CLDECDELETE(dir);
              }
	       }
       }
   }

   /**
   * So we can do some byte-to-hexchar conversion below
   */
	char HEX_DIGITS[] =
	{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

	char* FSDirectory::getLockPrefix() const{
		char dirName[CL_MAX_PATH]; // name to be hashed
		if ( _realpath(directory,dirName) == NULL ){
			_CLTHROWA(CL_ERR_Runtime,"Invalid directory path");
		}

		//to make a compatible name with jlucene, we need to make some changes...
		if ( dirName[1] == ':' )
			dirName[0] = (char)_totupper((char)dirName[0]);

		char* smd5 = MD5String(dirName);

		char* ret=_CL_NEWARRAY(char,32+7+1); //32=2*16, 7=strlen("lucene-")
		strcpy(ret,"lucene-");
		strcat(ret,smd5);
		
		_CLDELETE_CaARRAY(smd5);

	    return ret; 
  }

  bool FSDirectory::deleteFile(const char* name)  {
	CND_PRECONDITION(directory[0]!=0,"directory is not open");
    char fl[CL_MAX_DIR];
    priv_getFN(fl, name);
	return _unlink(fl) != -1;
  }

  void FSDirectory::renameFile(const char* from, const char* to){
	  CND_PRECONDITION(directory[0]!=0,"directory is not open");
    SCOPED_LOCK_MUTEX(THIS_LOCK)
    char old[CL_MAX_DIR];
    priv_getFN(old, from);

    char nu[CL_MAX_DIR];
    priv_getFN(nu, to);

    /* This is not atomic.  If the program crashes between the call to
    delete() and the call to renameTo() then we're screwed, but I've
    been unable to figure out how else to do this... */

    if ( Misc::dir_Exists(nu) )
      if( _unlink(nu) != 0 ){
	    char* err = _CL_NEWARRAY(char,16+strlen(to)+1); //16: len of "couldn't delete "
		strcpy(err,"couldn't delete ");
		strcat(err,to);
        _CLTHROWA_DEL(CL_ERR_IO, err );
      }
    if ( _rename(old,nu) != 0 ){
       //todo: jlucene has some extra rename code - if the rename fails, it copies
       //the whole file to the new file... might want to implement that if renaming
       //fails on some platforms
        char buffer[200];
        strcpy(buffer,"couldn't rename ");
        strcat(buffer,from);
        strcat(buffer," to ");
        strcat(buffer,to);
      _CLTHROWA(CL_ERR_IO, buffer );
    }
  }

  IndexOutput* FSDirectory::createOutput(const char* name) {
	CND_PRECONDITION(directory[0]!=0,"directory is not open");
    char fl[CL_MAX_DIR];
    priv_getFN(fl, name);
    return _CLNEW FSIndexOutput( fl );
  }

  LuceneLock* FSDirectory::makeLock(const char* name) {
	CND_PRECONDITION(directory[0]!=0,"directory is not open");

	char* tmp = getLockPrefix();
	char* lockFile = _CL_NEWARRAY(char,strlen(tmp)+strlen(name)+2);
	strcpy(lockFile,tmp);
	strcat(lockFile,"-");
	strcat(lockFile,name);
	_CLDELETE_CaARRAY(tmp);

    // create a lock file
    LuceneLock* ret = _CLNEW FSLock( lockDir, lockFile );
	_CLDELETE_CaARRAY(lockFile);
	return ret;
  }



  FSDirectory::FSLock::FSLock ( const char* _lockDir, const char* name )
  {
	  this->lockDir = STRDUP_AtoA(_lockDir);
	  strcpy(lockFile,_lockDir);
	  strcat(lockFile,PATH_DELIMITERA);
	  strcat(lockFile,name);
  }
  FSDirectory::FSLock::~FSLock(){
    _CLDELETE_LCaARRAY( lockDir );
  }
  TCHAR* FSDirectory::FSLock::toString(){
	  size_t lflen = strlen(lockFile);
	  TCHAR* ret = _CL_NEWARRAY(TCHAR,lflen+6);
	  _tcscpy(ret,_T("Lock@"));
	  STRCPY_AtoT(ret+5,lockFile,lflen+1);
	  return ret;
  }
  bool FSDirectory::FSLock::obtain() {
   if (LUCENE_DISABLE_LOCKS)
      return true;

	if ( Misc::dir_Exists(lockFile) )
	  return false;

	if ( !Misc::dir_Exists(lockDir) ){
       //todo: should construct directory using _mkdirs... have to write replacement
      if ( _mkdir(lockDir) == -1 ){
		  char* err = _CL_NEWARRAY(char,34+strlen(lockDir)+1); //34: len of "Couldn't create lock directory: "
		  strcpy(err,"Couldn't create lock directory: ");
		  strcat(err,lockDir);
		  _CLTHROWA_DEL(CL_ERR_IO, err );
      }
    }
    int32_t r = _open(lockFile,  O_RDWR | O_CREAT | O_RANDOM , _S_IREAD | _S_IWRITE); //must do this or file will be created Read only
	if ( r < 0 )
	  return false;
	else{
	  _close(r);
	  return true;
	}

  }
  bool FSDirectory::FSLock::isLocked(){
     if (LUCENE_DISABLE_LOCKS)
          return false;

     return Misc::dir_Exists(lockFile);
  }
  void FSDirectory::FSLock::release() {
    if (LUCENE_DISABLE_LOCKS)
          return;
    _unlink( lockFile );
  }

  TCHAR* FSDirectory::toString() const{
	  TCHAR* ret = _CL_NEWARRAY(TCHAR, strlen(this->directory) + 13); //strlen("FSDirectory@")
	  _tcscpy(ret,_T("FSDirectory@"));
	  STRCPY_AtoT(ret+12,directory,strlen(directory)+1);

	  return ret;
  }

CL_NS_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -