(in-package :netflix-packed-data) (defvar *byte-specs* '(:user-id (22 00) :movie-id (15 22) :stars (03 37) :date (12 40))) (defmacro user-id (rating ) `(ldb (byte ,@(getf *byte-specs* :user-id)) ,rating)) (defmacro movie-id (rating) `(ldb (byte ,@(getf *byte-specs* :movie-id)) ,rating)) (defmacro stars (rating) `(ldb (byte ,@(getf *byte-specs* :stars)) ,rating)) (defmacro date (rating) `(ldb (byte ,@(getf *byte-specs* :date)) ,rating)) (defmacro year (date) `(ldb (byte 3 9) ,date)) (defmacro month (date) `(ldb (byte 4 5) ,date)) (defmacro day (date) `(ldb (byte 5 0) ,date)) (defun unpack-date (date) (list (day date) (month date) (+ 1999 (year date)))) (defun unpack-rating (rating) (list :user-id (user-id rating) :movie-id (movie-id rating) :stars (stars rating) :date (unpack-date (date rating)))) (defun pack-date (year month day) (declare (fixnum year month day) (optimize (speed 3) (debug 0) (safety 0))) (let ((date 0)) (declare (fixnum date)) (setf (ldb (byte 5 0) date) day) (setf (ldb (byte 4 5) date) month) (setf (ldb (byte 3 9) date) (- year 1999)) date)) (defun parse-and-pack-date (string &key start) (declare (optimize (speed 1))) (destructuring-bind (year month day) (mapcar #'parse-integer (split-sequence:split-sequence #\- string :start start)) (pack-date year month day)))