git.fiddlerwoaroof.com
delta.lisp
d468a84b
 (in-package :fwoar.cl-git)
 
 (defmacro defclass+ (name (&rest super) &body (direct-slots &rest options))
   (let ((initargs (mapcan (lambda (slot)
                             (serapeum:unsplice
                              (make-symbol
                               (symbol-name
                                (getf (cdr slot)
                                      :initarg)))))
                           direct-slots)))
     `(progn (defclass ,name ,super
               ,direct-slots
               ,@options)
             (defun ,name (,@initargs)
               (fw.lu:new ',name ,@initargs)))))
 
 (defclass delta ()
   ((%repository :initarg :repository :reader repository)
    (%base :initarg :base :reader base)
    (%commands :initarg :commands :reader commands)))
 
 (defclass+ ofs-delta (delta)
   ())
 
 (defclass+ ref-delta (delta)
   ())
 
 (defun make-ofs-delta (base commands repository)
   (fw.lu:new 'ofs-delta base commands repository))
 (defun make-ref-delta (base commands repository)
   (fw.lu:new 'ofs-delta base commands repository))
 
f5b39481
 (defun int->bit-vector (n)
   (let* ((integer-length (integer-length n))
          (bv-size (* 8 (ceiling integer-length 8)))
          (bv (make-array bv-size :element-type 'bit)))
     (loop :for ix :below integer-length
           :do (setf (aref bv (- bv-size 1 ix))
                     (if (logbitp ix n)
                         1
                         0)))
     bv))
 
 (defun bit-vector->int (bv)
   (let ((bv-size (array-total-size bv)))
     (loop :for ix :from (1- bv-size) :downto 0
           :for n :from 0
           :unless (zerop (aref bv ix))
             :sum (expt 2 n))))
 
d468a84b
 (defun partition-commands (data)
   (let ((idx 0))
     (labels ((advance ()
                (prog1 (elt data idx)
                  (incf idx)))
              (get-command ()
f5b39481
                (let* ((bv (int->bit-vector (elt data idx)))
d468a84b
                       (discriminator (elt bv 0))
                       (insts (subseq bv 1)))
                  (incf idx)
                  (if (= 1 discriminator)
                      (list :copy
                            insts
                            (coerce (loop repeat (count 1 insts) collect (advance))
                                    '(vector (unsigned-byte 8))))
                      (list :add
f5b39481
                            (coerce (loop repeat (1- (bit-vector->int (reverse insts)))
d468a84b
                                          collect (advance))
                                    '(vector (unsigned-byte 8))))))))
       (loop while (< idx (length data))
             collect (get-command)))))
 
 (defmethod -extract-object-of-type ((type (eql :ofs-delta)) s repository &key offset-from)
   (format t "~&data: ~s~%" s)
   (make-ofs-delta offset-from
                   (partition-commands s)
                   repository))
 (defmethod -extract-object-of-type ((type (eql :ref-delta)) s repository &key offset-from)
   (make-ref-delta offset-from
                   (partition-commands s)
                   repository))
 
 
 #+(or) #+(or) #+(or)
 
 (defmethod component ((component (eql :tree)) (object git-commit))
   (ensure-ref
    (cadr
     (fw.lu:v-assoc :tree (metadata object)
                    :test 'string-equal))))
 (defmethod component ((component (eql :parents)) (object git-commit))
   (coerce (remove-if-not (serapeum:op
                            (string= "parent" _))
                          (metadata object)
                          :key #'car)
           'list))
 (defmethod component ((component (eql :message)) (object git-commit))
   (data object))