Changeset 2891

Show
Ignore:
Timestamp:
04/07/08 16:02:47 (8 months ago)
Author:
ksprotte
Message:

merged fixes to allocate-m2s-for-sale from trunk

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/bos/projects/bos/m2/allocation-test.lisp

    r2380 r2891  
    9292                (decf total-free size))))))) 
    9393 
     94(test allocation-area.auto-activation.2 
     95  (with-fixture empty-store () 
     96    (let* ((area1 (make-allocation-rectangle 0 0 8 8)) 
     97           (area2 (make-allocation-rectangle 10 10 8 8)) 
     98           (sponsor (make-sponsor :login "test-sponsor"))) 
     99      (is (not (allocation-area-active-p area1))) 
     100      (is (not (allocation-area-active-p area2))) 
     101      (dotimes (i 4) 
     102        (finishes (make-contract sponsor 16 :paidp t)) 
     103        (is (allocation-area-active-p area1)) 
     104        (is (not (allocation-area-active-p area2)))) 
     105      (finishes (make-contract sponsor 16 :paidp t)) 
     106      (is (allocation-area-active-p area1)) 
     107      (is (allocation-area-active-p area2))))) 
     108 
     109 
     110(test allocation-area.auto-activation.3 
     111  (dolist (m2-count '(1000 100)) 
     112    (with-fixture empty-store () 
     113      (let* ((area1 (make-allocation-rectangle 0 0 8 8)) 
     114             (area2 (make-allocation-rectangle 10 10 8 8)) 
     115             (sponsor (make-sponsor :login "test-sponsor"))) 
     116        (is (not (allocation-area-active-p area1))) 
     117        (is (not (allocation-area-active-p area2))) 
     118        (signals error (make-contract sponsor m2-count :paidp t)) 
     119        (is (not (allocation-area-active-p area1)) 
     120            "allocation areas should not be activated as a side effect, 
     121          when someone asks for too many m2s (~d) (which will result in 
     122          an error)" m2-count) 
     123        (is (not (allocation-area-active-p area2)) 
     124            "allocation areas should not be activated as a side effect, 
     125          when someone asks for too many m2s (~d) (which will result in 
     126          an error)" m2-count))))) 
     127 
     128(test allocation-area.auto-activation.4 
     129  (labels ((make-allocation-areas (widths) 
     130             (iter 
     131               (for w in widths) 
     132               (for pos initially 0 then (+ pos w)) 
     133               (collect (make-allocation-rectangle pos pos w w)))) 
     134           (request-feasible-p (n areas) 
     135             (some #'(lambda (area) (<= n (allocation-area-free-m2s area))) areas))) 
     136    (for-all ((allocation-area-widths  (gen-list :length (gen-integer :min 1 :max 5) 
     137                                                 :elements (gen-integer :min 1 :max 20))) 
     138              (n (gen-integer :min 1 :max 100))) 
     139      (with-fixture empty-store () 
     140        (let* ((areas (make-allocation-areas allocation-area-widths)) 
     141               (sponsor (make-sponsor :login "test-sponsor"))) 
     142          (is (notany #'allocation-area-active-p areas)) 
     143          (is (every #'bos.m2::allocation-area-consistent-p areas)) 
     144          (cond 
     145            ((request-feasible-p n areas) 
     146             (finishes (make-contract sponsor n :paidp t)) 
     147             (is (= 1 (count-if #'allocation-area-active-p areas))) 
     148             (is (every #'bos.m2::allocation-area-consistent-p areas))) 
     149            (t 
     150             (signals error (make-contract sponsor n :paidp t)) 
     151             (is (notany #'allocation-area-active-p areas)) 
     152             (is (every #'bos.m2::allocation-area-consistent-p areas))))))))) 
     153 
     154(test allocation-area.allocate-m2s-for-sale 
     155  (flet ((m2p (obj) 
     156           (typep obj 'm2))) 
     157    (with-fixture empty-store () 
     158      (let* ((area1 (make-allocation-rectangle 0 0 8 8)) 
     159             (area2 (make-allocation-rectangle 10 10 9 9))) 
     160        (for-all ((n (gen-integer :min 1 :max 60))) 
     161          (let ((m2s (with-transaction () (bos.m2::allocate-m2s-for-sale n))))         
     162            (if (null m2s) 
     163                (pass) 
     164                (progn 
     165                  (is (listp m2s)) 
     166                  (is (every #'m2p m2s)) 
     167                  (is (= n (length m2s))))))))))) 
     168 
     169(test allocation-area.allocate-m2s-for-sale.2 
     170  (flet ((m2p (obj) 
     171           (typep obj 'm2))) 
     172    (for-all ((n (gen-integer :min 1 :max 290))) 
     173      (with-fixture empty-store () 
     174        (let* ((area1 (make-allocation-rectangle 0 0 8 8)) 
     175               (area2 (make-allocation-rectangle 10 10 9 9)) 
     176               (m2s (with-transaction () (bos.m2::allocate-m2s-for-sale n)))) 
     177          (if (null m2s) 
     178              (pass) 
     179              (progn 
     180                (is (listp m2s)) 
     181                (is (every #'m2p m2s)) 
     182                (is (= n (length m2s)))))))))) 
     183 
     184 
     185 
  • branches/bos/projects/bos/m2/allocation.lisp

    r2665 r2891  
    183183  (remove-if-not #'allocation-area-active-p (all-allocation-areas))) 
    184184 
    185 (defun find-inactive-allocation-area () 
    186   (find-if #'(lambda (allocation-area) (not (or (allocation-area-active-p allocation-area) 
    187                                                 (null (allocation-area-free-m2s allocation-area))))) 
    188            (all-allocation-areas))) 
     185(defun find-inactive-nonempty-allocation-areas () 
     186  (remove-if-not #'(lambda (allocation-area) 
     187                     (not (or (allocation-area-active-p allocation-area) 
     188                              (null (allocation-area-free-m2s allocation-area))))) 
     189                 (all-allocation-areas))) 
    189190 
    190191(deftransaction activate-allocation-area (area) 
     
    632633           append (allocation-area-stripes area)))) 
    633634 
    634 (defun find-free-m2s (n) 
    635   (assert (plusp n)) 
    636   (unless (in-transaction-p) 
    637     (error "find-free-m2s called outside of the allocation transaction")) 
    638   (or (bos.m2.allocation-cache:find-exact-match n :remove t)  
    639       (some (lambda (area) (allocation-area-find-free-m2s area n)) 
    640             (active-allocation-areas)) 
    641       (let ((area (find-inactive-allocation-area))) 
    642         (when area 
    643           (activate-allocation-area area) 
    644           (find-free-m2s n))) 
    645       (find-free-m2s/underflow n) 
    646       (warn "all allocation areas exhausted") 
    647       nil)) 
     635(defun allocate-m2s-for-sale (n) 
     636  "The main entry point to the allocation machinery.  Will return a 
     637list of N m2 instances or NIL if the requested amount cannot be 
     638allocated. 
     639Returned m2s will not be allocated again (i.e. there are 
     640marked as in use) by the allocation algorithm, but see RETURN-M2S." 
     641  (labels ((allocate-in-active-areas (n) 
     642             (or (bos.m2.allocation-cache:find-exact-match n :remove t)  
     643                 (some (lambda (area) (allocation-area-find-free-m2s area n)) 
     644                       (active-allocation-areas)))) 
     645           (can-possibly-allocate-request (n) 
     646             (find n (all-allocation-areas) :key #'allocation-area-free-m2s :test #'<=)) 
     647           (allocate-without-activation (area n)                
     648             (let ((status (allocation-area-active-p area))) 
     649               (unwind-protect 
     650                    (progn 
     651                      (setf (slot-value area 'active-p) t) 
     652                      (allocate-in-active-areas n)) 
     653                 (setf (slot-value area 'active-p) status))))) 
     654    (assert (plusp n)) 
     655    (unless (in-transaction-p) 
     656      (error "find-free-m2s called outside of the allocation transaction")) 
     657    (or (allocate-in-active-areas n) 
     658        (unless (can-possibly-allocate-request n) 
     659          (return-from allocate-m2s-for-sale nil))           
     660        (loop 
     661           for area in (find-inactive-nonempty-allocation-areas) 
     662           for m2s = (allocate-without-activation area n)  
     663           when m2s 
     664           do (activate-allocation-area area) and 
     665           return m2s) 
     666        (find-free-m2s/underflow n) 
     667        nil))) 
    648668 
    649669(defmethod return-m2s (m2s) 
     
    717737             (- (stripe-y stripe) (stripe-top stripe))) 
    718738          (* (stripe-width stripe) (stripe-height stripe)))) 
     739 
     740 
     741(defun allocation-area-consistent-p (allocation-area) 
     742  (let ((total (calculate-total-m2-count allocation-area)) 
     743        (allocated (calculate-allocated-m2-count allocation-area)) 
     744        (consistent-p t)) 
     745    (unless (= total (allocation-area-total-m2s allocation-area)) 
     746      (warn "~s's total count is ~d but should be ~d" 
     747            allocation-area (allocation-area-total-m2s allocation-area) total) 
     748      (setf consistent-p nil)) 
     749    (unless (= (- total allocated) (allocation-area-free-m2s allocation-area)) 
     750      (warn "~s's free count is ~d but should be ~d" 
     751            allocation-area (allocation-area-free-m2s allocation-area) (- total allocated)) 
     752      (setf consistent-p nil)) 
     753    consistent-p)) 
     754 
  • branches/bos/projects/bos/m2/m2.lisp

    r2418 r2891  
    381381 
    382382(deftransaction do-make-contract (sponsor m2-count &key date paidp expires download-only) 
    383   (let ((m2s (find-free-m2s m2-count))) 
     383  (let ((m2s (allocate-m2s-for-sale m2-count))) 
    384384    (if m2s 
    385385        (let ((contract (make-object 'contract