~ubuntu-branches/ubuntu/trusty/librep/trusty

« back to all changes in this revision

Viewing changes to lisp/rep/data/ring.jl

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2001-11-13 15:06:22 UTC
  • Revision ID: james.westby@ubuntu.com-20011113150622-vgmgmk6srj3kldr3
Tags: upstream-0.15.2
ImportĀ upstreamĀ versionĀ 0.15.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#| ring.jl -- ring buffer support
 
2
 
 
3
   $Id: ring.jl,v 1.8 2001/08/08 06:00:19 jsh Exp $
 
4
 
 
5
   Copyright (C) 1993, 1994, 2000 John Harper <john@dcs.warwick.ac.uk>
 
6
 
 
7
   This file is part of librep.
 
8
 
 
9
   librep is free software; you can redistribute it and/or modify it
 
10
   under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 2, or (at your option)
 
12
   any later version.
 
13
 
 
14
   librep is distributed in the hope that it will be useful, but
 
15
   WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
 
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with librep; see the file COPYING.  If not, write to
 
21
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
22
|#
 
23
 
 
24
(define-structure rep.data.ring
 
25
 
 
26
    (export ring-capacity
 
27
            ring-size
 
28
            make-ring
 
29
            ring-append
 
30
            ring-ref
 
31
            ring-replace
 
32
            ring->list
 
33
            add-to-ring
 
34
            get-from-ring
 
35
            set-ring-head)
 
36
 
 
37
    (open rep
 
38
          rep.data.datums)
 
39
 
 
40
  (define-structure-alias ring rep.data.ring)
 
41
 
 
42
  ;; default size of a ring buffer
 
43
  (defconst default-size 16)
 
44
 
 
45
  ;; key for datum access
 
46
  (define key (cons))
 
47
 
 
48
  (define-datum-printer key (lambda (d s)
 
49
                              (declare (unused d))
 
50
                              (write s "#<ring>")))
 
51
 
 
52
  ;; A ring buffer of size N is defined by a vector with N+2 slots; the
 
53
  ;; first slot is used to store the size of the buffer, the second stores
 
54
  ;; the position of the next slot to be filled.
 
55
 
 
56
  (define (ring-capacity ring)
 
57
    "Returns the number of slots in the ring buffer RING."
 
58
    (- (length (datum-ref ring key)) 2))
 
59
 
 
60
  (define (ring-size ring)
 
61
    "Returns the number of filled slots in the ring buffer RING."
 
62
    (aref (datum-ref ring key) 0))
 
63
 
 
64
  (define (set-size ring size)
 
65
    (aset (datum-ref ring key) 0 size))
 
66
 
 
67
  (define (get-pos ring)
 
68
    (aref (datum-ref ring key) 1))
 
69
  (define (set-pos ring pos)
 
70
    (aset (datum-ref ring key) 1 pos))
 
71
 
 
72
  (define (get-item ring pos)
 
73
    (aref (datum-ref ring key) (+ pos 2)))
 
74
  (define (set-item ring pos val)
 
75
    (aset (datum-ref ring key) (+ pos 2) val))
 
76
 
 
77
;;; higher level public api
 
78
 
 
79
  (define (make-ring #!optional size)
 
80
    "Create a ring buffer that can contain SIZE values. If SIZE is not
 
81
specified the default capacity `ring-default-size' is used."
 
82
    (unless size (setq size default-size))
 
83
    (let ((ring (make-datum (make-vector (+ size 2)) key)))
 
84
      (set-size ring 0)
 
85
      (set-pos ring 0)
 
86
      ring))
 
87
 
 
88
  (define (ring-append ring object)
 
89
    "Append OBJECT to the ring buffer RING. This may overwrite a previously
 
90
added object."
 
91
    (set-item ring (get-pos ring) object)
 
92
    (let ((new-pos (mod (1+ (get-pos ring)) (ring-capacity ring))))
 
93
      (unless (= (ring-size ring) (ring-capacity ring))
 
94
        (set-size ring (1+ (ring-size ring))))
 
95
      (set-pos ring new-pos)))
 
96
 
 
97
  (define (ring-ref ring #!optional depth)
 
98
    "Read an object from the ring buffer RING. If DEPTH is true it
 
99
defines the object to access, the most recently added item is at
 
100
depth zero, the next at depth one, and so on. If there is no item at
 
101
DEPTH nil is returned."
 
102
    (unless depth (setq depth 0))
 
103
    (if (>= depth (ring-capacity ring))
 
104
        nil
 
105
      (get-item ring (mod (- (get-pos ring) (1+ depth))
 
106
                          (ring-capacity ring)))))
 
107
 
 
108
  (define (ring-replace ring object)
 
109
    "Replaces the most recently added object in ring buffer RING with OBJECT.
 
110
If RING contains no items, add OBJECT as the first."
 
111
    (if (zerop (ring-size ring))
 
112
        (add-to-ring ring object)
 
113
      (set-item ring (mod (1- (get-pos ring)) (ring-capacity ring)) object)))
 
114
 
 
115
  (define (ring->list ring)
 
116
    "Return the elements in ring buffer RING as a list, newest to oldest."
 
117
    (let ((size (ring-size ring))
 
118
          (contents '()))
 
119
      (do ((i 0 (1+ i)))
 
120
          ((= i size) (nreverse contents))
 
121
        (setq contents (cons (ring-ref ring i) contents)))))
 
122
 
 
123
;;; compatibility api
 
124
 
 
125
  (define (get-from-ring ring #!optional depth)
 
126
    (ring-ref ring (if depth (1- depth) 0)))
 
127
  (define add-to-ring ring-append)
 
128
  (define set-ring-head ring-replace))