X-Git-Url: http://dolda2000.com/gitweb/?p=didex.git;a=blobdiff_plain;f=didex%2Findex.py;h=cdd40695600e4bd70b9ae5c2c3d05df6fb237ae0;hp=4d4250663b4eb23c468fe04931b208befb781526;hb=bd14729f305c077e65963fba4aeaab3baf8ee653;hpb=abb94f836b21e1fe76e83675dd09b4236a689a45 diff --git a/didex/index.py b/didex/index.py index 4d42506..cdd4069 100644 --- a/didex/index.py +++ b/didex/index.py @@ -2,6 +2,8 @@ import struct, contextlib, math from . import db, lib from .db import bd, txnfun +__all__ = ["maybe", "t_int", "t_uint", "t_float", "t_str", "ordered"] + deadlock = bd.DBLockDeadlockError notfound = bd.DBNotFoundError @@ -47,6 +49,45 @@ class maybe(object): else: return self.bk.compare(a[1:], b[1:]) +class compound(object): + def __init__(self, *parts): + self.parts = parts + + def encode(self, obs): + if len(obs) != len(self.parts): + raise ValueError("invalid length of compound data: " + str(len(obs)) + ", rather than " + len(self.parts)) + buf = bytearray() + for ob, part in zip(obs, self.parts): + dat = part.encode(ob) + if len(dat) < 128: + buf.append(0x80 | len(dat)) + buf.extend(dat) + else: + buf.extend(struct.pack(">i", len(dat))) + buf.extend(dat) + return bytes(buf) + def decode(self, dat): + ret = [] + off = 0 + for part in self.parts: + if dat[off] & 0x80: + ln = dat[off] & 0x7f + off += 1 + else: + ln = struct.unpack(">i", dat[off:off + 4])[0] + off += 4 + ret.append(part.decode(dat[off:off + len])) + off += len + return tuple(ret) + def compare(self, al, bl): + if (len(al) != len(self.parts)) or (len(bl) != len(self.parts)): + raise ValueError("invalid length of compound data: " + str(len(al)) + ", " + str(len(bl)) + ", rather than " + len(self.parts)) + for a, b, part in zip(al, bl, self.parts): + c = part.compare(a, b) + if c != 0: + return c + return 0 + def floatcmp(a, b): if math.isnan(a) and math.isnan(b): return 0