Package xappy :: Module fieldmappings
[frames] | no frames]

Source Code for Module xappy.fieldmappings

  1  #!/usr/bin/env python 
  2  # 
  3  # Copyright (C) 2007 Lemur Consulting Ltd 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  #  
 15  # You should have received a copy of the GNU General Public License along 
 16  # with this program; if not, write to the Free Software Foundation, Inc., 
 17  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 18  r"""fieldmappings.py: Mappings from field names to term prefixes, etc. 
 19   
 20  """ 
 21  __docformat__ = "restructuredtext en" 
 22   
 23  import cPickle as _cPickle 
 24   
25 -class FieldMappings(object):
26 """Mappings from field names to term prefixes, slot values, etc. 27 28 The following mappings are maintained: 29 30 - a mapping from field name to the string prefix to insert at the start of 31 terms. 32 - a mapping from field name to the slot numbers to store the field contents 33 in. 34 35 """ 36 __slots__ = '_prefixes', '_prefixcount', '_slots', '_slotcount', 37
38 - def __init__(self, serialised=None):
39 """Create a new field mapping object, or unserialise a saved one. 40 41 """ 42 if serialised is not None: 43 (self._prefixes, self._prefixcount, 44 self._slots, self._slotcount) = _cPickle.loads(serialised) 45 else: 46 self._prefixes = {} 47 self._prefixcount = 0 48 self._slots = {} 49 self._slotcount = 0
50
51 - def _genPrefix(self):
52 """Generate a previously unused prefix. 53 54 Prefixes are uppercase letters, and start with 'X' (this is a Xapian 55 convention, for compatibility with other Xapian tools: other starting 56 letters are reserved for special meanings): 57 58 >>> maps = FieldMappings() 59 >>> maps._genPrefix() 60 'XA' 61 >>> maps._genPrefix() 62 'XB' 63 >>> [maps._genPrefix() for i in xrange(60)] 64 ['XC', 'XD', 'XE', 'XF', 'XG', 'XH', 'XI', 'XJ', 'XK', 'XL', 'XM', 'XN', 'XO', 'XP', 'XQ', 'XR', 'XS', 'XT', 'XU', 'XV', 'XW', 'XX', 'XY', 'XZ', 'XAA', 'XBA', 'XCA', 'XDA', 'XEA', 'XFA', 'XGA', 'XHA', 'XIA', 'XJA', 'XKA', 'XLA', 'XMA', 'XNA', 'XOA', 'XPA', 'XQA', 'XRA', 'XSA', 'XTA', 'XUA', 'XVA', 'XWA', 'XXA', 'XYA', 'XZA', 'XAB', 'XBB', 'XCB', 'XDB', 'XEB', 'XFB', 'XGB', 'XHB', 'XIB', 'XJB'] 65 >>> maps = FieldMappings() 66 >>> [maps._genPrefix() for i in xrange(27*26 + 5)][-10:] 67 ['XVZ', 'XWZ', 'XXZ', 'XYZ', 'XZZ', 'XAAA', 'XBAA', 'XCAA', 'XDAA', 'XEAA'] 68 """ 69 res = [] 70 self._prefixcount += 1 71 num = self._prefixcount 72 while num != 0: 73 ch = (num - 1) % 26 74 res.append(chr(ch + ord('A'))) 75 num -= ch 76 num = num // 26 77 return 'X' + ''.join(res)
78
79 - def get_fieldname_from_prefix(self, prefix):
80 """Get a fieldname from a prefix. 81 82 If the prefix is not found, return None. 83 84 """ 85 for key, val in self._prefixes.iteritems(): 86 if val == prefix: 87 return key 88 return None
89
90 - def get_prefix(self, fieldname):
91 """Get the prefix used for a given field name. 92 93 """ 94 return self._prefixes[fieldname]
95
96 - def get_slot(self, fieldname, purpose):
97 """Get the slot number used for a given field name and purpose. 98 99 """ 100 return self._slots[(fieldname, purpose)]
101
102 - def add_prefix(self, fieldname):
103 """Allocate a prefix for the given field. 104 105 If a prefix is already allocated for this field, this has no effect. 106 107 """ 108 if fieldname in self._prefixes: 109 return 110 self._prefixes[fieldname] = self._genPrefix()
111
112 - def add_slot(self, fieldname, purpose, slotnum=None):
113 """Allocate a slot number for the given field and purpose. 114 115 If a slot number is already allocated for this field and purpose, this 116 has no effect. 117 118 Returns the slot number allocated for the field and purpose (whether 119 newly allocated, or previously allocated). 120 121 If `slotnum` is supplied, the number contained in it is used to 122 allocate the new slot, instead of allocating a new number. No checks 123 will be made to ensure that the slot number doesn't collide with 124 existing (or later allocated) numbers: the main purpose of this 125 parameter is to share allocations - ie, to collide deliberately. 126 127 """ 128 try: 129 return self._slots[(fieldname, purpose)] 130 except KeyError: 131 pass 132 133 if slotnum is None: 134 self._slots[(fieldname, purpose)] = self._slotcount 135 self._slotcount += 1 136 return self._slotcount - 1 137 else: 138 self._slots[(fieldname, purpose)] = slotnum 139 return slotnum
140
141 - def serialise(self):
142 """Serialise the field mappings to a string. 143 144 This can be unserialised by passing the result of this method to the 145 constructor of a new FieldMappings object. 146 147 """ 148 return _cPickle.dumps((self._prefixes, 149 self._prefixcount, 150 self._slots, 151 self._slotcount, 152 ), 2)
153