Commit c5bba5979c3468fa0c579c66561e61edd803bd61

Thomas de Grivel 2017-06-21T11:48:43

bordeaux-set

diff --git a/bordeaux-queue.asd b/bordeaux-queue.asd
deleted file mode 100644
index 1e09cbf..0000000
--- a/bordeaux-queue.asd
+++ /dev/null
@@ -1,17 +0,0 @@
-
-(in-package :common-lisp-user)
-
-(defpackage :bordeaux-queue.system
-  (:use :common-lisp :asdf))
-
-(in-package :bordeaux-queue.system)
-
-(defsystem "bordeaux-queue"
-  :name "bordeaux-queue"
-  :author "Thomas de Grivel <thoxdg@gmail.com>"
-  :version "0.1"
-  :description "Re-entrant queue using bordeaux-threads."
-  :depends-on ("bordeaux-threads")
-  :components
-  ((:file "package")
-   (:file "bordeaux-queue" :depends-on ("package"))))
diff --git a/bordeaux-queue.lisp b/bordeaux-queue.lisp
deleted file mode 100644
index e66fba9..0000000
--- a/bordeaux-queue.lisp
+++ /dev/null
@@ -1,114 +0,0 @@
-
-(in-package :bordeaux-queue)
-
-(deftype fixnum+ (&optional (low 0))
-  `(integer ,low ,most-positive-fixnum))
-
-(deftype fixnum* (&optional (low 1))
-  `(integer ,low ,most-positive-fixnum))
-
-(defclass queue ()
-  ((vector :initarg :vector
-	   :reader queue-vector
-	   :type simple-vector)
-   (read-index :initform 0
-	       :accessor queue-read-index
-	       :type fixnum+)
-   (write-index :initform 0
-		:accessor queue-write-index
-		:type fixnum+)
-   (length :initform 0
-	   :accessor queue-length
-	   :type fixnum+)
-   (lock :initform (make-lock 'queue)
-	 :reader queue-lock)))
-
-(defclass queue-blocking-write (queue)
-  ((blocking-write-cv :initform (make-condition-variable
-				 :name "queue blocking write")
-		      :reader queue-blocking-write-cv)))
-
-(defgeneric enqueue-full (queue))
-
-(defgeneric enqueue (queue item &optional blocking))
-
-(defgeneric on-dequeue (queue))
-(defgeneric dequeue (queue))
-(defgeneric dequeue-all (queue))
-
-;;  Initialization
-
-(defun make-queue-vector (size &optional (element-type 't) initial-element)
-  (declare (type fixnum* size))
-  (assert (typep initial-element element-type))
-  (make-array `(,size)
-	      :element-type element-type
-	      :initial-element initial-element))
-
-(defmethod initialize-instance ((q queue) &rest initargs
-				&key size (element-type 't)
-				  initial-element &allow-other-keys)
-  (let ((vector (make-queue-vector size element-type initial-element)))
-    (apply #'call-next-method q (list* :vector vector initargs))))
-
-(defun make-queue (size)
-  (make-instance 'queue :size size))
-
-;;  Enqueue
-
-(defmethod enqueue-full ((q queue))
-  nil)
-
-(defmethod enqueue-full ((q queue-blocking-write))
-  (with-accessors ((lock queue-lock)
-		   (blocking-write-cv queue-blocking-write-cv)) q
-    (condition-wait blocking-write-cv lock)))
-
-(defmethod enqueue ((q queue) item &optional blocking)
-  (assert (typep item (array-element-type (queue-vector q))))
-  (with-accessors ((vector queue-vector)
-		   (write-index queue-write-index)
-		   (length queue-length)
-		   (lock queue-lock)) q
-    (with-lock-held (lock)
-      (labels ((fetch ()
-		 (let ((vector-length (length vector))
-		       (len length))
-		   (cond ((= len vector-length)
-			  (when blocking
-			    (enqueue-full q)
-			    (fetch)))
-			 ((< len vector-length)
-			  (setf write-index (mod (1+ write-index) vector-length)
-				length (1+ len))
-			  t)
-			 (t
-			  (error "Invalid queue length"))))))
-	(fetch)))))
-
-;;  Dequeue
-
-(defmethod on-dequeue ((q queue))
-  nil)
-
-(defmethod on-dequeue ((q queue-blocking-write))
-  (condition-notify (queue-blocking-write-cv q)))
-
-(defmethod dequeue ((q queue))
-  (with-accessors ((vector queue-vector)
-		   (read-index queue-read-index)
-		   (length queue-length)
-		   (lock queue-lock)) q
-    (with-lock-held (lock)
-      (let ((vector-length (length vector))
-	    (len length))
-	(cond ((= 0 len)
-	       (values nil nil))
-	      ((< 0 len)
-	       (let ((item (aref vector read-index)))
-		 (setf read-index (mod (1+ read-index) vector-length)
-		       length (1- len))
-		 (on-dequeue q)
-		 (values item t)))
-	      (t
-	       (error "Invalid queue length")))))))
diff --git a/bordeaux-set.asd b/bordeaux-set.asd
new file mode 100644
index 0000000..74ae2a4
--- /dev/null
+++ b/bordeaux-set.asd
@@ -0,0 +1,17 @@
+
+(in-package :common-lisp-user)
+
+(defpackage :bordeaux-set.system
+  (:use :common-lisp :asdf))
+
+(in-package :bordeaux-set.system)
+
+(defsystem "bordeaux-set"
+  :name "bordeaux-set"
+  :author "Thomas de Grivel <thoxdg@gmail.com>"
+  :version "0.1"
+  :description "Re-entrant set using bordeaux-threads."
+  :depends-on ("bordeaux-threads")
+  :components
+  ((:file "package")
+   (:file "bordeaux-set" :depends-on ("package"))))
diff --git a/bordeaux-set.lisp b/bordeaux-set.lisp
new file mode 100644
index 0000000..1b6ddb2
--- /dev/null
+++ b/bordeaux-set.lisp
@@ -0,0 +1,46 @@
+
+(in-package :bordeaux-set)
+
+(deftype fixnum+ (&optional (low 0))
+  `(integer ,low ,most-positive-fixnum))
+
+(defclass set ()
+  ((hash-table :initarg :hash-table
+	       :initform (make-hash-table)
+	       :reader set-hash-table
+	       :type hash-table)
+   (size :initform 0
+	 :accessor set-size
+	 :type fixnum+)
+   (lock :initform (make-lock "set")
+	 :reader set-lock)))
+
+(defgeneric set-add (set item))
+(defgeneric set-remove (set item))
+(defgeneric set-member-p (set item))
+(defgeneric set-empty-p (set))
+(defgeneric do-set (fn set))
+
+(defmethod set-add ((set set) item)
+  (with-lock-held ((set-lock set))
+    (setf (gethash item (set-hash-table set)) t)
+    (incf (set-size set))))
+
+(defmethod set-remove ((set set) item)
+  (with-lock-held ((set-lock set))
+    (remhash item (set-hash-table set))
+    (decf (set-size set))))
+
+(defmethod set-member-p ((set set) item)
+  (with-lock-held ((set-lock set))
+    (gethash item (set-hash-table set))))
+
+(defmethod set-empty-p ((set set))
+  (= 0 (set-size set)))
+
+(defmethod set-each ((fn function) (set set))
+  (with-lock-held ((set-lock set))
+    (maphash (lambda (key value)
+	       (declare (ignore value))
+	       (funcall fn key))
+	     (set-hash-table set))))
diff --git a/package.lisp b/package.lisp
index 7f73173..051659f 100644
--- a/package.lisp
+++ b/package.lisp
@@ -1,10 +1,13 @@
 
 (in-package :common-lisp)
 
-(defpackage :bordeaux-queue
+(defpackage :bordeaux-set
   (:use :bordeaux-threads :common-lisp)
+  (:shadow
+   #:set)
   (:export
-   #:queue
-   #:enqueue
-   #:dequeue
-   #:dequeue-all))
+   #:set
+   #:set-add
+   #:set-remove
+   #:set-member-p
+   #:set-each))