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

📄 curia.rb

📁 一个小型的基于Hash的Key=>Value的数据库
💻 RB
📖 第 1 页 / 共 2 页
字号:
#=================================================================================================# Ruby API of Curia, the basic 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_curia'require 'thread'### require 'curia'# The library `curia' should be included in application codes.# An instance of the class `Curia' is used as a database handle.# `Curia' performs Mix-in of `Enumerable'.# Each method of `Curia' throws an exception of `Curia::EANY' or its sub classes when an error# occurs: `Curia::ENOERR', `Curia::EFATAL', `Curia::EMODE', `Curia::EBROKEN', `Curia::EKEEP',# `Curia::ENOITEM', `Curia::EALLOC', `Curia::EMAP', `Curia::EOPEN', `Curia::ECLOSE',# `Curia::ETRUNC', `Curia::ESYNC', `Curia::ESTAT', `Curia::ESEEK', `Curia::EREAD',# `Curia::EWRITE', `Curia::ELOCK', `Curia::EUNLINK', `Curia::EMKDIR', `Curia::ERMDIR' and# `Curia::EMISC'.#class Curia  include Mod_Curia, Enumerable  #----------------------------------------------------------------  # class constants  #----------------------------------------------------------------  MyMutex = Mutex::new()  #----------------------------------------------------------------  # class methods  #----------------------------------------------------------------  public  ##  # curia = Curia::new(name, omode, bnum, dnum)  # Constructor: Get a database handle.  # `name' specifies the name of a database directory.  # `omode' specifies the connection mode: `Curia::OWRITER' as a writer, `Curia::OREADER' as a  # reader.  If the mode is `Curia::OWRITER', the following may be added by bitwise or:  # `Curia::OCREAT', which means it creates a new database if not exist, `Curia::OTRUNC', which  # means it creates a new database regardless if one exists.  Both of `Curia::OREADER' and  # `Curia::OWRITER' can be added to by bitwise or: `Curia::ONOLCK', which means it opens a  # database directory without file locking, or `Curia::OLCKNB', which means locking is  # performed without blocking.  `Curia::OCREAT' can be added to by bitwise or: `Curia::OSPARSE',  # which means it creates database files as sparse files.  If it is omitted, `Curia::OREADER'  # is specified.  # `bnum' specifies the number of elements of the bucket array.  If it is omitted or not more  # than 0, the default value is specified.  The size of a bucket array is determined on  # creating, and can not be changed except for by optimization of the database.  Suggested  # size of a bucket array is about from 0.5 to 4 times of the number of all records to store.  # `dnum' specifies the number of division of the database.  If it is omitted or not more than  # 0, the default value is specified.  The number of division can not be changed from the  # initial value.  The max number of division is 512.  # The return value is the database handle.  # An exception of `Curia::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 directory.  # While connecting as a reader, a shared lock is invoked to the database directory.  The thread  # blocks until the lock is achieved.  If `Curia::ONOLCK' is used, the application is  # responsible for exclusion control.  #  #@ DEFINED IMPLICITLY  ##  # curia = Curia::open(name, omode, bnum, dnum)  # Constructor: An alias of `new'.  #  #@ DEFINED OUTSIDE  #----------------------------------------------------------------  # private methods  #----------------------------------------------------------------  private  #=  # initialize(name, omode, bnum)  # Method: Called implicitly by the constructor.  #  def initialize(name, omode = OREADER, bnum = -1, dnum = -1)    @silent = false    MyMutex.synchronize() do      @index = mod_open(name, omode, bnum, dnum)      @name = name    end    if(iterator?)      begin        yield(self)      ensure        close()      end    end    self  end  #=  # clone()  # Method: Forbidden to use.  #  def clone    raise(CuriaError)  end  #=  # dup()  # Method: Forbidden to use.  #  alias dup clone  #----------------------------------------------------------------  # public methods  #----------------------------------------------------------------  public  ##  # bool = curia.close()  # Method: Close the database handle.  # The return value is always true.  # An exception of `Curia::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.  #  def close()    MyMutex.synchronize() do      begin        mod_close(@index)      ensure        @index = -1      end    end  end  ##  # curia.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 = curia.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: `Curia::DOVER',  # which means the specified value overwrites the existing one, `Curia::DKEEP', which means  # the existing value is kept, `Curia::DCAT', which means the specified value is concatenated  # at the end of the existing value.  If it is omitted, `Curia::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 `Curia::EANY' or its sub classes is thrown if an error occurs or replace  # is cancelled.  #  def put(key, val, dmode = DOVER)    mod_put(@index, key, val, dmode)  end  ##  # bool = curia.store(key, val)  # Method: An alias of `put'.  #  alias store put  ##  # curia[key] = val  # Method: An alias of `put'.  #  alias []= put  ##  # bool = curia.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 `Curia::EANY' or its sub classes is thrown if an error occurs or no record  # corresponds.  #  def out(key)    mod_out(@index, key)  end  ##  # bool = curia.delete(key)  # Method: An alias of `out'.  #  alias delete out  ##  # bool = curia.clear()  # Method: Delete all records.  # The return value is always true.  # An exception of `Curia::EANY' or its sub classes is thrown if an error occurs.  #  def clear    MyMutex.synchronize() do      iterinit()      while(rnum() > 0)        out(iternext())      end    end    true  end  ##  # str = curia.get(key, start, max)  # Method: Retrieve a record.  # `key' specifies a key.  Although it must be an instance of String, binary data is okey.  # `start' specifies the offset address of the beginning of the region of the value to be read.  # If it is negative or omitted, the offset is specified as 0.  # `max' specifies the max size to be read.  If it is negative or omitted, the size to read is  # unlimited.  # 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.  # An exception of `Curia::EANY' or its sub classes is thrown if an error occurs, no record  # corresponds, or the size of the value of the corresponding record is less than `max'.  #  def get(key, start = 0, max = -1)    mod_get(@index, key, start, max)  end  ##  # str = curia.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 `Curia::EANY' or its sub classes is thrown if an error occurs.  #  def fetch(key, defval = nil)    if @silent      if val = mod_get(@index, key, 0, -1)        val      else        defval      end    else      begin        mod_get(@index, key, 0, -1)      rescue ENOITEM        defval      end    end  end  ##  # str = curia[key]  # Method: An alias of `fetch'.  #  alias [] fetch  ##  # num = curia.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.  # An exception of `Curia::EANY' or its sub classes is thrown if an error occurs or no record  # corresponds.  # Because this method does not read the entity of a record, it is faster than `get'.  #  def vsiz(key)    mod_vsiz(@index, key)  end  ##  # bool = curia.iterinit()  # Method: Initialize the iterator of the database handle.  # The return value is always true.  # An exception of `Curia::EANY' or its sub classes is thrown if an error occurs.  # The iterator is used in order to access the key of every record stored in a database.  #  def iterinit()    mod_iterinit(@index)  end  ##  # str = curia.iternext()  # Method: Get the next key of the iterator.  # The return value is the value of the next key.  If the silent flag is true and no record  # corresponds, nil is returned instead of exception.  # An exception of `Curia::EANY' or its sub classes is thrown if an error occurs or no record  # is to be get out of the iterator.  # It is possible to access every record by iteration of calling this method.  However, it is  # not assured if updating the database is occurred while the iteration.  Besides, the order  # of this traversal access method is arbitrary, so it is not assured that the order of  # storing matches the one of the traversal access.  #  def iternext()    mod_iternext(@index)  end  ##  # bool = curia.setalign(align)  # Method: Set alignment of the database handle.  # `align' specifies the basic size of alignment.  If it is omitted, alignment is cleared.  # The return value is always true.  # An exception of `Curia::EANY' or its sub classes is thrown if an error occurs.  # If alignment is set to a database, the efficiency of overwriting values is improved.  # The size of alignment is suggested to be average size of the values of the records to be

⌨️ 快捷键说明

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