1 /*
2  * This file is part of d-dazzle.
3  *
4  * d-dazzle is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * d-dazzle is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with d-dazzle; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 module dazzle.Heap;
20 
21 private import dazzle.c.functions;
22 public  import dazzle.c.types;
23 private import glib.ConstructionException;
24 private import glib.MemorySlice;
25 private import glib.Str;
26 private import gobject.ObjectG;
27 private import gtkd.Loader;
28 
29 
30 /**
31  * Heaps are similar to a partially sorted tree but implemented as an
32  * array. They allow for efficient O(1) lookup of the highest priority
33  * item as it will always be the first item of the array.
34  * 
35  * To create a new heap use dzl_heap_new().
36  * 
37  * To add items to the heap, use dzl_heap_insert_val() or
38  * dzl_heap_insert_vals() to insert in bulk.
39  * 
40  * To access an item in the heap, use dzl_heap_index().
41  * 
42  * To remove an arbitrary item from the heap, use dzl_heap_extract_index().
43  * 
44  * To remove the highest priority item in the heap, use dzl_heap_extract().
45  * 
46  * To free a heap, use dzl_heap_unref().
47  * 
48  * Here is an example that stores integers in a #DzlHeap:
49  * |[<!-- language="C" -->
50  * static int
51  * cmpint (gconstpointer a,
52  * gconstpointer b)
53  * {
54  * return *(const gint *)a - *(const gint *)b;
55  * }
56  * 
57  * int
58  * main (gint   argc,
59  * gchar *argv[])
60  * {
61  * DzlHeap *heap;
62  * gint i;
63  * gint v;
64  * 
65  * heap = dzl_heap_new (sizeof (gint), cmpint);
66  * 
67  * for (i = 0; i < 10000; i++)
68  * dzl_heap_insert_val (heap, i);
69  * for (i = 0; i < 10000; i++)
70  * dzl_heap_extract (heap, &v);
71  * 
72  * dzl_heap_unref (heap);
73  * }
74  * ]|
75  */
76 public final class Heap
77 {
78 	/** the main Gtk struct */
79 	protected DzlHeap* dzlHeap;
80 	protected bool ownedRef;
81 
82 	/** Get the main Gtk struct */
83 	public DzlHeap* getHeapStruct(bool transferOwnership = false)
84 	{
85 		if (transferOwnership)
86 			ownedRef = false;
87 		return dzlHeap;
88 	}
89 
90 	/** the main Gtk struct as a void* */
91 	protected void* getStruct()
92 	{
93 		return cast(void*)dzlHeap;
94 	}
95 
96 	/**
97 	 * Sets our main struct and passes it to the parent class.
98 	 */
99 	public this (DzlHeap* dzlHeap, bool ownedRef = false)
100 	{
101 		this.dzlHeap = dzlHeap;
102 		this.ownedRef = ownedRef;
103 	}
104 
105 	~this ()
106 	{
107 		if ( Linker.isLoaded(LIBRARY_DAZZLE) && ownedRef )
108 			dzl_heap_unref(dzlHeap);
109 	}
110 
111 
112 	/** */
113 	public @property string data()
114 	{
115 		return Str.toString(dzlHeap.data);
116 	}
117 
118 	/** Ditto */
119 	public @property void data(string value)
120 	{
121 		dzlHeap.data = Str.toStringz(value);
122 	}
123 
124 	/** */
125 	public @property size_t len()
126 	{
127 		return dzlHeap.len;
128 	}
129 
130 	/** Ditto */
131 	public @property void len(size_t value)
132 	{
133 		dzlHeap.len = value;
134 	}
135 
136 	/** */
137 	public static GType getType()
138 	{
139 		return dzl_heap_get_type();
140 	}
141 
142 	/**
143 	 * Creates a new #DzlHeap. A heap is a tree-like structure stored in
144 	 * an array that is not fully sorted, but head is guaranteed to be either
145 	 * the max, or min value based on @compare_func. This is also known as
146 	 * a priority queue.
147 	 *
148 	 * Params:
149 	 *     elementSize = the size of each element in the heap
150 	 *     compareFunc = a function to compare to elements
151 	 *
152 	 * Returns: A newly allocated #DzlHeap
153 	 *
154 	 * Throws: ConstructionException GTK+ fails to create the object.
155 	 */
156 	public this(uint elementSize, GCompareFunc compareFunc)
157 	{
158 		auto p = dzl_heap_new(elementSize, compareFunc);
159 
160 		if(p is null)
161 		{
162 			throw new ConstructionException("null returned by new");
163 		}
164 
165 		this(cast(DzlHeap*) p);
166 	}
167 
168 	/** */
169 	public bool extract(void* result)
170 	{
171 		return dzl_heap_extract(dzlHeap, result) != 0;
172 	}
173 
174 	/** */
175 	public bool extractIndex(size_t index, void* result)
176 	{
177 		return dzl_heap_extract_index(dzlHeap, index, result) != 0;
178 	}
179 
180 	/** */
181 	public void insertVals(void* data, uint len)
182 	{
183 		dzl_heap_insert_vals(dzlHeap, data, len);
184 	}
185 
186 	alias doref = ref_;
187 	/**
188 	 * Increments the reference count of @heap by one.
189 	 *
190 	 * Returns: @heap
191 	 */
192 	public Heap ref_()
193 	{
194 		auto p = dzl_heap_ref(dzlHeap);
195 
196 		if(p is null)
197 		{
198 			return null;
199 		}
200 
201 		return ObjectG.getDObject!(Heap)(cast(DzlHeap*) p, true);
202 	}
203 
204 	/**
205 	 * Decrements the reference count of @heap by one, freeing the structure
206 	 * when the reference count reaches zero.
207 	 */
208 	public void unref()
209 	{
210 		dzl_heap_unref(dzlHeap);
211 	}
212 }