commit
c1eae16cdb
5 changed files with 175 additions and 0 deletions
@ -0,0 +1,21 @@
|
||||
MIT License |
||||
|
||||
Copyright (c) Michael Fiano |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
@ -0,0 +1,24 @@
|
||||
# dynamic-array |
||||
|
||||
An implementation of the AVL tree data structure. |
||||
|
||||
An optimized 1-dimensional array of fixnums that automatically re-adjusts in size. |
||||
|
||||
## Overview |
||||
|
||||
An optimized 1-dimensional array type that can only store fixnums, and which is able to |
||||
automatically grow when pushing new elements to the end. It is not very useful in most situations, |
||||
as it doesn't implement the Common Lisp sequences protocol, nor does it conform to the usual |
||||
interface of Common Lisp arrays for PUSH and POP. |
||||
|
||||
## Install |
||||
|
||||
```lisp |
||||
(ql:quickload :dynamic-array) |
||||
``` |
||||
|
||||
## License |
||||
|
||||
Copyright © 2019-2022 Michael Fiano <mail@mfiano.net> |
||||
|
||||
Licensed under the MIT License. |
@ -0,0 +1,13 @@
|
||||
(asdf:defsystem #:dynamic-array |
||||
:description "An optimized 1-dimensional array of fixnums that automatically re-adjusts in size." |
||||
:author "Michael Fiano <mail@mfiano.net>" |
||||
:license "MIT" |
||||
:homepage "https://github.com/mfiano/dynamic-array" |
||||
:version "0.1.0" |
||||
:encoding :utf-8 |
||||
:depends-on (#:mfiano-utils) |
||||
:pathname "src" |
||||
:serial t |
||||
:components |
||||
((:file "package") |
||||
(:file "dynamic-array"))) |
@ -0,0 +1,92 @@
|
||||
(in-package #:dynamic-array) |
||||
|
||||
(declaim (inline %make-array)) |
||||
(defstruct (dynamic-array |
||||
(:constructor %make-array) |
||||
(:conc-name nil) |
||||
(:predicate nil) |
||||
(:copier nil)) |
||||
(data (cl:make-array 0 :element-type t) :type simple-vector) |
||||
(initial-element 0) |
||||
(fill-pointer 0 :type fixnum)) |
||||
|
||||
(u:define-printer (dynamic-array stream :type nil) |
||||
(format stream "~{~a~^ ~}" |
||||
(coerce (subseq (data dynamic-array) 0 (fill-pointer dynamic-array)) 'list))) |
||||
|
||||
(defun make-array (&key (size 0) (capacity 128) (element-type t) |
||||
initial-element) |
||||
(assert (<= size capacity)) |
||||
(let ((data (cl:make-array capacity :element-type element-type :initial-element initial-element))) |
||||
(%make-array :data data :initial-element initial-element :fill-pointer size))) |
||||
|
||||
(u:fn-> copy (dynamic-array) dynamic-array) |
||||
(defun copy (dynamic-array) |
||||
(declare (optimize speed)) |
||||
(%make-array :data (u:copy-array (data dynamic-array)) |
||||
:initial-element (initial-element dynamic-array) |
||||
:fill-pointer (fill-pointer dynamic-array))) |
||||
|
||||
(u:fn-> length (dynamic-array) fixnum) |
||||
(declaim (inline length)) |
||||
(defun length (dynamic-array) |
||||
(fill-pointer dynamic-array)) |
||||
|
||||
(u:fn-> aref (dynamic-array fixnum) t) |
||||
(declaim (inline aref)) |
||||
(defun aref (dynamic-array index) |
||||
(declare (optimize speed)) |
||||
(if (< index (fill-pointer dynamic-array)) |
||||
(locally (declare (optimize (safety 0))) |
||||
(cl:aref (data dynamic-array) index)) |
||||
(error "Index out of bounds."))) |
||||
|
||||
(u:fn-> (setf aref) (t dynamic-array fixnum) t) |
||||
(declaim (inline (setf aref))) |
||||
(defun (setf aref) (value dynamic-array index) |
||||
(declare (optimize speed)) |
||||
(if (< index (fill-pointer dynamic-array)) |
||||
(locally (declare (optimize (safety 0))) |
||||
(setf (cl:aref (data dynamic-array) index) value)) |
||||
(error "Index out of bounds."))) |
||||
|
||||
(u:fn-> pop (dynamic-array &optional boolean) t) |
||||
(declaim (inline pop)) |
||||
(defun pop (dynamic-array &optional delete-p) |
||||
(declare (optimize speed)) |
||||
(let ((data (data dynamic-array)) |
||||
(length (fill-pointer dynamic-array))) |
||||
(unless (zerop length) |
||||
(prog1 (cl:aref data (decf (fill-pointer dynamic-array))) |
||||
(when delete-p |
||||
(setf (cl:aref data (1- length)) nil)))))) |
||||
|
||||
(u:fn-> push (dynamic-array t) dynamic-array) |
||||
(defun push (dynamic-array value) |
||||
(declare (optimize speed)) |
||||
(let* ((data (data dynamic-array)) |
||||
(length (cl:length data)) |
||||
(fill-pointer (fill-pointer dynamic-array))) |
||||
(when (= fill-pointer length) |
||||
(let ((data (adjust-array |
||||
data |
||||
(max 16 (min (* length 2) most-positive-fixnum)) |
||||
:initial-element (initial-element dynamic-array)))) |
||||
(setf (data dynamic-array) data))) |
||||
(locally (declare (optimize (safety 0))) |
||||
(setf (cl:aref (data dynamic-array) fill-pointer) value) |
||||
(incf (fill-pointer dynamic-array))) |
||||
dynamic-array)) |
||||
|
||||
(u:fn-> map (dynamic-array function) null) |
||||
(defun map (dynamic-array func) |
||||
(declare (optimize speed)) |
||||
(loop :for i :below (length dynamic-array) |
||||
:for element = (aref dynamic-array i) |
||||
:do (funcall func element))) |
||||
|
||||
(u:fn-> find (dynamic-array t &key (:test function) (:key function)) t) |
||||
(declaim (inline find)) |
||||
(defun find (dynamic-array item &key (test #'eql) key) |
||||
(declare (optimize speed)) |
||||
(cl:find item (data dynamic-array) :key key :test test)) |
@ -0,0 +1,25 @@
|
||||
(in-package #:cl-user) |
||||
|
||||
(defpackage #:dynamic-array |
||||
(:local-nicknames |
||||
(#:u #:mfiano-utils)) |
||||
(:use #:cl) |
||||
(:shadow |
||||
#:aref |
||||
#:fill-pointer |
||||
#:find |
||||
#:length |
||||
#:make-array |
||||
#:map |
||||
#:pop |
||||
#:push) |
||||
(:export |
||||
#:aref |
||||
#:copy |
||||
#:dynamic-array |
||||
#:find |
||||
#:length |
||||
#:make-array |
||||
#:map |
||||
#:pop |
||||
#:push)) |
Loading…
Reference in new issue