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

📄 villa.rb

📁 一个小型的基于Hash的Key=>Value的数据库
💻 RB
📖 第 1 页 / 共 2 页
字号:
#=================================================================================================# Ruby API of Villa, the advanced API of QDBM#                                                       Copyright (C) 2000-2006 Mikio Hirabayashi# This file is part of QDBM, Quick Database Manager.# QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU# Lesser General Public License as published by the Free Software Foundation; either version# 2.1 of the License or any later version.  QDBM is distributed in the hope that it will be# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more# details.# You should have received a copy of the GNU Lesser General Public License along with QDBM; if# not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA# 02111-1307 USA.#=================================================================================================require 'mod_villa'require 'thread'### require 'villa'# The library `villa' should be included in application codes.# An instance of the class `Villa' is used as a database handle.# `Villa' performs Mix-in of `Enumerable'.# Each method of `Villa' throws an exception of `Villa::EANY' or its sub classes when an error# occurs: `Villa::ENOERR', `Villa::EFATAL', `Villa::EMODE', `Villa::EBROKEN', `Villa::EKEEP',# `Villa::ENOITEM', `Villa::EALLOC', `Villa::EMAP', `Villa::EOPEN', `Villa::ECLOSE',# `Villa::ETRUNC', `Villa::ESYNC', `Villa::ESTAT', `Villa::ESEEK', `Villa::EREAD',# `Villa::EWRITE', `Villa::ELOCK', `Villa::EUNLINK', `Villa::EMKDIR', `Villa::ERMDIR' and# `Villa::EMISC'.#class Villa  include Mod_Villa, Enumerable  #----------------------------------------------------------------  # class constants  #----------------------------------------------------------------  MyMutex = Mutex::new()  #----------------------------------------------------------------  # class methods  #----------------------------------------------------------------  public  ##  # villa = Villa::new(name, omode, cmode)  # Constructor: Get a database handle.  # `name' specifies the name of a database file.  # `omode' specifies the connection mode: `Villa::OWRITER' as a writer, `Villa::OREADER' as a  # reader.  If the mode is `Villa::OWRITER', the following may be added by bitwise or:  # `Villa::OCREAT', which means it creates a new database if not exist, `Villa::OTRUNC', which  # means it creates a new database regardless if one exists, `Villa::OZCOMP', which means  # leaves in the database are compressed with ZLIB, `Villa::OYCOMP', which means leaves in the  # database are compressed with LZO, `Villa::OXCOMP', which means leaves in the database are  # compressed with BZIP2.  Both of `Villa::OREADER' and `Villa::OWRITER' can be added to by  # bitwise or: `Villa::ONOLCK', which means it opens a database file without file locking, or  # `Villa::OLCKNB', which means locking is performed without blocking.  If it is omitted,  # `Villa::OREADER' is specified.  # `cmode' specifies the comparing function: `Villa::CMPLEX' comparing keys in lexical order,  # `Villa::CMPDEC' comparing keys as decimal strings, `Villa::CMPOBJ' comparing keys as  # serialized objects implementing the method `<=>'.  The comparing function should be kept  # same in the life of a database.  If `Villa::CMPOBJ' is used, such methods as `put', `out',  # `get' and so on can treat not only instances of `String' but also any serializable and  # comparable object.  # If so, objects being stored are serialized and objects being retrieved are deserialized.  # The return value is the database handle.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs.  # If a block parameter is given, this method works as an iterator.  A database handle is  # opened and passed via the first argument of the block.  The database handle is surely  # closed when the block is over.  # While connecting as a writer, an exclusive lock is invoked to the database file.  # While connecting as a reader, a shared lock is invoked to the database file.  The thread  # blocks until the lock is achieved.  `Villa::OZCOMP', `Villa::OYCOMP', and `Villa::OXCOMP'  # are available only if QDBM was built each with ZLIB, LZO, and BZIP2 enabled.  If  # `Villa::ONOLCK' is used, the application is responsible for exclusion control.  #  #@ DEFINED IMPLICITLY  ##  # villa = Villa::open(name, omode, cmode)  # Constructor: An alias of `new'.  #  #@ DEFINED OUTSIDE  #----------------------------------------------------------------  # private methods  #----------------------------------------------------------------  private  #=  # initialize(name, omode, cmode)  # Method: Called implicitly by the constructor.  #  def initialize(name, omode = OREADER, cmode = CMPLEX)    @silent = false    MyMutex.synchronize() do      @index = mod_open(name, omode, cmode)      @name = name      @cmode = cmode      @tranmutex = Mutex::new()    end    if(iterator?)      begin        yield(self)      ensure        close()      end    end    self  end  #=  # clone()  # Method: Forbidden to use.  #  def clone    raise(VillaError)  end  #=  # dup()  # Method: Forbidden to use.  #  alias dup clone  #----------------------------------------------------------------  # public methods  #----------------------------------------------------------------  public  ##  # bool = villa.close()  # Method: Close the database handle.  # The return value is always true.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs.  # Because the region of a closed handle is released, it becomes impossible to use the handle.  # Updating a database is assured to be written when the handle is closed.  If a writer opens  # a database but does not close it appropriately, the database will be broken.  If the  # transaction is activated and not committed, it is aborted.  #  def close()    MyMutex.synchronize() do      begin        mod_close(@index)      ensure        @index = -1      end    end  end  ##  # villa.silent = bool  # Method: Set the flag whether to repress frequent exceptions.  # The return value is the assigned value.  #  def silent=(value)    @silent = value ? true : false    mod_setsilent(@index, silent ? 1 : 0)    @silent  end  def silent    @silent  end  ##  # bool = villa.put(key, val, dmode)  # Method: Store a record.  # `key' specifies a key.  Although it must be an instance of String, binary data is okey.  # `val' specifies a value.  Although it must be an instance of String, binary data is okey.  # `dmode' specifies behavior when the key overlaps, by the following values: `Villa::DOVER',  # which means the specified value overwrites the existing one, `Villa::DKEEP', which means the  # existing value is kept, `Villa::DCAT', which means the specified value is concatenated at the  # end of the existing value, `Villa::DDUP', which means duplication of keys is allowed and the  # specified value is added as the last one, `Villa::DDUPR', which means duplication of keys is  # allowed and the specified value is added as the first one.  If it is omitted, `Villa::DOVER'  # is specified.  # The return value is always true.  However, if the silent flag is true and replace is  # cancelled, false is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or replace  # is cancelled.  # The cursor becomes unavailable due to updating database.  #  def put(key, val, dmode = DOVER)    if(@cmode == CMPOBJ)      key = Marshal.dump(key)      val = Marshal.dump(val)    end    mod_put(@index, key, val, dmode)  end  ##  # bool = villa.store(key, val)  # Method: An alias of `put'.  #  alias store put  ##  # villa[key] = val  # Method: An alias of `put'.  #  alias []= put  ##  # bool = villa.out(key)  # Method: Delete a record.  # `key' specifies a key.  Although it must be an instance of String, binary data is okey.  # The return value is always true.  However, if the silent flag is true and no record  # corresponds, false is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or no record  # corresponds.  # When the key of duplicated records is specified, the value of the first record of the same  # key is selected.  The cursor becomes unavailable due to updating database.  #  def out(key)    if(@cmode == CMPOBJ)      key = Marshal.dump(key)    end    mod_out(@index, key)  end  ##  # bool = villa.delete(key)  # Method: An alias of `out'.  #  alias delete out  ##  # bool = villa.clear()  # Method: Delete all records.  # The return value is always true.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs.  #  def clear    MyMutex.synchronize() do      begin        while(rnum() > 0)          curfirst();          out(curkey())        end      rescue ENOITEM      end    end    true  end  ##  # str = villa.get(key)  # Method: Retrieve a record.  # `key' specifies a key.  Although it must be an instance of String, binary data is okey.  # The return value is an instance of the value of the corresponding record.  If the silent flag  # is true and no record corresponds, nil is returned instead of exception.  # When the key of duplicated records is specified, the first record of the same key is  # deleted.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or no record  # corresponds.  #  def get(key)    if(@cmode == CMPOBJ)      key = Marshal.dump(key)    end    val = mod_get(@index, key)    if(@cmode == CMPOBJ && val)      val = Marshal.load(val)    end    val  end  ##  # str = villa.fetch(key, defval)  # Method: Retrieve a record.  # `key' specifies a key.  Although it must be an instance of String, binary data is okey.  # `defval' specifies the default value used when no record corresponds.  If it is omitted, nil  # is specified.  # The return value is an instance of the value of the corresponding record, or the default  # value if no record corresponds.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs.  #  def fetch(key, defval = nil)    if @silent      if val = mod_get(@index, key)        if(@cmode == CMPOBJ)          val = Marshal.load(val)        end        val      else        defval      end    else      begin        val = mod_get(@index, key)        if(@cmode == CMPOBJ)          val = Marshal.load(val)        end        val      rescue ENOITEM        defval      end    end  end  ##  # str = villa[key]  # Method: An alias of `fetch'.  #  alias [] fetch  ##  # num = villa.vsiz(key)  # Method: Get the size of the value of a record.  # `key' specifies a key.  Although it must be an instance of String, binary data is okey.  # The return value is the size of the value of the corresponding record.  If the silent flag  # is true and no record corresponds, -1 is returned instead of exception.  If multiple records  # correspond, the size of the first is returned.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs.  #  def vsiz(key)    if(@cmode == CMPOBJ)      key = Marshal.dump(key)    end    mod_vsiz(@index, key)  end  ##  # num = villa.vnum(key)  # Method: Get the number of records corresponding a key.  # `key' specifies a key.  Although it must be an instance of String, binary data is okey.  # The return value is the size of the value of the corresponding record.  If no record  # corresponds, 0 is returned.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs.  #  def vnum(key)    if(@cmode == CMPOBJ)      key = Marshal.dump(key)    end    mod_vnum(@index, key)  end  ##  # bool = villa.curfirst()  # Method: Move the cursor to the first record.  # The return value is always true.  However, if the silent flag is true and no record  # corresponds, false is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or there is  # no record in the database.  #  def curfirst()    mod_curfirst(@index)  end  ##  # bool = villa.curlast()  # Method: Move the cursor to the last record.  # The return value is always true.  However, if the silent flag is true and no record  # corresponds, false is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or there is  # no record in the database.  #  def curlast()    mod_curlast(@index)  end  ##  # bool = villa.curprev()  # Method: Move the cursor to the previous record.  # The return value is always true.  However, if the silent flag is true and no record  # corresponds, false is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or there is  # no previous record.  #  def curprev()    mod_curprev(@index)  end  ##  # bool = villa.curnext()  # Method: Move the cursor to the next record.  # The return value is always true.  However, if the silent flag is true and no record  # corresponds, false is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or there is  # no next record.  #  def curnext()    mod_curnext(@index)  end  ##  # bool = villa.curjump(key, jmode)  # Method: Move the cursor to a position around a record.  # `key' specifies a key.  Although it must be an instance of String, binary data is okey.  # `jmode' specifies detail adjustment: `Villa::JFORWARD', which means that the cursor is set  # to the first record of the same key and that the cursor is set to the next substitute if  # completely matching record does not exist, `Villa::JBACKWARD', which means that the cursor  # is set to the last record of the same key and that the cursor is set to the previous  # substitute if completely matching record does not exist.  If it is omitted, `Villa::JFORWARD'  # is specified.  # The return value is always true.  However, if the silent flag is true and no record  # corresponds, false is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or there is  # no record corresponding the condition.  #  def curjump(key, jmode = JFORWARD)    if(@cmode == CMPOBJ)      key = Marshal.dump(key)    end    mod_curjump(@index, key, jmode)  end  ##  # str = villa.curkey()  # Method: Get the key of the record where the cursor is.  # The return value is the key of the corresponding record.  If the silent flag is true and no  # record corresponds, nil is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or no record  # corresponds to the cursor.  #  def curkey()    key = mod_curkey(@index)    if(@cmode == CMPOBJ && key)      key = Marshal.load(key)    end    key  end  ##  # str = villa.curval()  # Method: Get the value of the record where the cursor is.  # The return value is the value of the corresponding record.  If the silent flag is true and no  # record corresponds, nil is returned instead of exception.  # An exception of `Villa::EANY' or its sub classes is thrown if an error occurs or no record  # corresponds to the cursor.  #  def curval()    val = mod_curval(@index)    if(@cmode == CMPOBJ && val)      val = Marshal.load(val)    end    val

⌨️ 快捷键说明

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