source: branches/lispworks/q.lisp@ 18

Last change on this file since 18 was 7, checked in by Gail Zacharias, 17 years ago

Credit for Anvita

  • Property svn:eol-style set to native
File size: 3.5 KB
Line 
1;;;-*- Mode: Lisp; Package: Wood -*-
2
3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4;;
5;; q.lisp
6;; A simple fifo queue. Why isn't this part of Common Lisp
7;;
8;; Portions Copyright © 2006 Clozure Associates and Anvita eReference (www.Anvita.info)
9;; Copyright © 1996 Digitool, Inc.
10;; Copyright © 1992-1995 Apple Computer, Inc.
11;; All rights reserved.
12;; Permission is given to use, copy, and modify this software provided
13;; that Digitool is given credit in all derivative works.
14;; This software is provided "as is". Digitool makes no warranty or
15;; representation, either express or implied, with respect to this software,
16;; its quality, accuracy, merchantability, or fitness for a particular
17;; purpose.
18
19;;;;;;;;;;;;;;;;;;;;;;;;;;
20;;
21;; Modification History
22;;
23;; 02/01/06 gz LispWorks port
24;; ------------- 0.96
25;; 08/27/96 bill Added copyright and mod history comments
26;;
27
28(in-package #+ccl :ccl #-ccl :wood)
29
30(export '(make-q enq deq q-empty-p))
31
32#+ccl (require "LISPEQU") ; %cons-pool, pool.data
33
34(defstruct q
35 start-buf
36 start-index
37 end-buf
38 end-index)
39
40(defmethod print-object ((q q) stream)
41 (print-unreadable-object (q stream :type t :identity t)
42 ))
43
44(defconstant $q-buf-size 512)
45#+Lispworks (defconstant $max-num-q-bufs 20)
46
47(defvar *q-bufs*
48 #+ccl (%cons-pool)
49 #+LispWorks (let ((arr (make-array $max-num-q-bufs)))
50 (hcl:set-array-weak arr t)
51 arr))
52
53(defun make-q-buf ()
54 (without-interrupts
55 #+ccl
56 (let ((buf (pool.data *q-bufs*)))
57 (if buf
58 (progn
59 (setf (pool.data *q-bufs*) (svref buf 0))
60 (dotimes (i $q-buf-size)
61 (setf (svref buf i) nil))
62 buf)
63 (make-array $q-buf-size)))
64 #+LispWorks
65 (let ((pos (position-if-not #'null *q-bufs*)))
66 (if pos
67 (let ((buf (aref *q-bufs* pos)))
68 (setf (aref *q-bufs* pos) nil)
69 (fill buf nil)
70 buf)
71 (make-array $q-buf-size)))))
72
73(defun free-q-buf (buf)
74 (without-interrupts
75 #+ccl
76 (setf (svref buf 0) (pool.data *q-bufs*)
77 (pool.data *q-bufs*) buf)
78 #+LispWorks
79 (let ((pos (position-if #'null *q-bufs*)))
80 (when pos
81 (setf (aref *q-bufs* pos) buf)))
82 nil))
83
84(defun enq (q elt)
85 (setq q (require-type q 'q))
86 (let ((buf (q-end-buf q))
87 (index (q-end-index q)))
88 (if (null buf)
89 (setf buf (make-q-buf)
90 (q-start-buf q) buf
91 (q-start-index q) 1
92 (q-end-buf q) buf
93 (q-end-index q) (setq index 1))
94 (when (>= index $q-buf-size)
95 (setf (q-end-buf q)
96 (setf buf
97 (setf (svref buf 0) (make-q-buf)))
98 (q-end-index q) (setq index 1))))
99 (setf (svref buf index) elt)
100 (setf (q-end-index q) (1+ index)))
101 elt)
102
103(defun q-empty-p (q)
104 (setq q (require-type q 'q))
105 (let ((start-buf (q-start-buf q)))
106 (or (null start-buf)
107 (and (eq start-buf (q-end-buf q))
108 (eql (q-start-index q)
109 (q-end-index q))))))
110
111(defun deq (q &optional (error-if-empty t))
112 (when (q-empty-p q)
113 (if error-if-empty
114 (error "Empty q: ~s" q)
115 (return-from deq nil)))
116 (let ((buf (q-start-buf q))
117 (index (q-start-index q)))
118 (prog1
119 (svref buf index)
120 (when (eql (incf index) $q-buf-size)
121 (setq index 1)
122 (unless (setf (q-start-buf q) (svref buf 0))
123 (setf (q-end-buf q) nil))
124 (free-q-buf buf))
125 (setf (q-start-index q) index))))
126
127(provide "Q")
128;;; 1 3/10/94 bill 1.8d247
Note: See TracBrowser for help on using the repository browser.