sublattice.mx raw

   1  package iskra
   2  
   3  import "git.smesh.lol/iskradb/lattice"
   4  
   5  // SubLattice is a domain-scoped view of an iskradb tree.
   6  // All keys in a sub-lattice share the same domain byte, ensuring
   7  // non-collision with other domains in the same physical tree.
   8  type SubLattice struct {
   9  	Tree   *lattice.Tree
  10  	Pool   []byte
  11  	Domain uint8
  12  }
  13  
  14  // NewSubLattice creates a SubLattice view over an existing tree.
  15  func NewSubLattice(tree *lattice.Tree, pool []byte, domain uint8) SubLattice {
  16  	return SubLattice{Tree: tree, Pool: pool, Domain: domain}
  17  }
  18  
  19  // MakeKey returns the key for (word, coord) in this sub-lattice's domain.
  20  // The word is normalized via the registered KeyNormalizer for the domain.
  21  func (sl SubLattice) MakeKey(coord uint64, word string) lattice.Key {
  22  	return MakeKey(sl.Domain, coord, NormalizeKey(sl.Domain, word))
  23  }
  24  
  25  // Translate finds the best match for word in dstDomain by:
  26  // 1. Looking up word in src sub-lattice at coord
  27  // 2. Following Record.Link[0] to the primary cross-domain translation
  28  // 3. Reading the target form from the dst sub-lattice record
  29  //
  30  // coord should encode the semantic/morph context of word in the source domain.
  31  // RelaxCoord is applied if the exact coord is not found.
  32  func Translate(src, dst SubLattice, word string, coord uint64) string {
  33  	norm := NormalizeKey(src.Domain, word)
  34  	branches := [3]lattice.Branch{lattice.Bnoun, lattice.Bverb, lattice.Bmodifier}
  35  
  36  	for _, c := range RelaxCoord(coord) {
  37  		key := MakeKey(src.Domain, c, norm)
  38  		for _, b := range branches {
  39  			ri := src.Tree.LookupRecIdx(b, key)
  40  			if ri == lattice.NullRec {
  41  				continue
  42  			}
  43  			rec := src.Tree.GetRecord(ri)
  44  			if rec == nil || rec.Link[0] == lattice.NullRec {
  45  				continue
  46  			}
  47  			dst_rec := dst.Tree.GetRecord(rec.Link[0])
  48  			if dst_rec == nil {
  49  				continue
  50  			}
  51  			n := int(dst_rec.Inline[23])
  52  			if n > 0 && n <= 23 {
  53  				return string(dst_rec.Inline[:n])
  54  			}
  55  			if dst_rec.DataFile == 1 && dst_rec.DataLen > 0 {
  56  				end := dst_rec.DataOff + dst_rec.DataLen
  57  				if int(end) <= len(dst.Pool) {
  58  					return string(dst.Pool[dst_rec.DataOff:end])
  59  				}
  60  			}
  61  		}
  62  	}
  63  	return ""
  64  }
  65  
  66  // Compose registers src as a sub-lattice within dst's tree by sharing the
  67  // physical tree. Since domain bytes differ, keys cannot collide.
  68  // Both sub-lattices must use the same physical *lattice.Tree.
  69  // This is a conceptual operation - the tree is already shared if both
  70  // SubLattices were created from the same tree pointer.
  71  func Compose(a, b SubLattice) bool {
  72  	return a.Tree == b.Tree
  73  }
  74