2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 #include <libkern/c++/OSOrderedSet.h>
27 #include <libkern/c++/OSLib.h>
29 #define super OSCollection
31 OSDefineMetaClassAndStructors(OSOrderedSet
, OSCollection
)
32 OSMetaClassDefineReservedUnused(OSOrderedSet
, 0);
33 OSMetaClassDefineReservedUnused(OSOrderedSet
, 1);
34 OSMetaClassDefineReservedUnused(OSOrderedSet
, 2);
35 OSMetaClassDefineReservedUnused(OSOrderedSet
, 3);
36 OSMetaClassDefineReservedUnused(OSOrderedSet
, 4);
37 OSMetaClassDefineReservedUnused(OSOrderedSet
, 5);
38 OSMetaClassDefineReservedUnused(OSOrderedSet
, 6);
39 OSMetaClassDefineReservedUnused(OSOrderedSet
, 7);
43 extern int debug_container_malloc_size
;
45 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
51 const OSMetaClassBase
* obj
;
57 initWithCapacity(unsigned int inCapacity
,
58 OSOrderFunction inOrdering
, void *inOrderingRef
)
65 size
= sizeof(_Element
) * inCapacity
;
66 array
= (_Element
*) kalloc(size
);
71 capacity
= inCapacity
;
72 capacityIncrement
= (inCapacity
)? inCapacity
: 16;
73 ordering
= inOrdering
;
74 orderingRef
= inOrderingRef
;
82 OSOrderedSet
* OSOrderedSet::
83 withCapacity(unsigned int capacity
,
84 OSOrderFunction ordering
, void * orderingRef
)
86 OSOrderedSet
*me
= new OSOrderedSet
;
88 if (me
&& !me
->initWithCapacity(capacity
, ordering
, orderingRef
)) {
96 void OSOrderedSet::free()
101 kfree((vm_offset_t
)array
, sizeof(_Element
) * capacity
);
102 ACCUMSIZE( -(sizeof(_Element
) * capacity
) );
108 unsigned int OSOrderedSet::getCount() const { return count
; }
109 unsigned int OSOrderedSet::getCapacity() const { return capacity
; }
110 unsigned int OSOrderedSet::getCapacityIncrement() const
111 { return capacityIncrement
; }
112 unsigned int OSOrderedSet::setCapacityIncrement(unsigned int increment
)
114 capacityIncrement
= (increment
)? increment
: 16;
115 return capacityIncrement
;
118 unsigned int OSOrderedSet::ensureCapacity(unsigned int newCapacity
)
121 int oldSize
, newSize
;
123 if (newCapacity
<= capacity
)
127 newCapacity
= (((newCapacity
- 1) / capacityIncrement
) + 1)
129 newSize
= sizeof(_Element
) * newCapacity
;
131 newArray
= (_Element
*) kalloc(newSize
);
133 oldSize
= sizeof(_Element
) * capacity
;
135 ACCUMSIZE(newSize
- oldSize
);
137 bcopy(array
, newArray
, oldSize
);
138 bzero(&newArray
[capacity
], newSize
- oldSize
);
139 kfree((vm_offset_t
)array
, oldSize
);
141 capacity
= newCapacity
;
147 void OSOrderedSet::flushCollection()
153 for (i
= 0; i
< count
; i
++)
154 array
[i
].obj
->taggedRelease(OSTypeID(OSCollection
));
160 bool OSOrderedSet::setObject(unsigned int index
, const OSMetaClassBase
*anObject
)
163 unsigned int newCount
= count
+ 1;
165 if ((index
> count
) || !anObject
)
168 if (containsObject(anObject
))
171 // do we need more space?
172 if (newCount
> capacity
&& newCount
> ensureCapacity(newCount
))
176 if (index
!= count
) {
177 for (i
= count
; i
> index
; i
--)
178 array
[i
] = array
[i
-1];
180 array
[index
].obj
= anObject
;
181 // array[index].pri = pri;
182 anObject
->taggedRetain(OSTypeID(OSCollection
));
189 bool OSOrderedSet::setFirstObject(const OSMetaClassBase
*anObject
)
191 return( setObject(0, anObject
));
194 bool OSOrderedSet::setLastObject(const OSMetaClassBase
*anObject
)
196 return( setObject( count
, anObject
));
200 #define ORDER(obj1,obj2) \
201 (ordering ? ((*ordering)( (OSObject *) obj1, (OSObject *) obj2, orderingRef)) : 0)
203 bool OSOrderedSet::setObject(const OSMetaClassBase
*anObject
)
207 // queue it behind those with same priority
209 (i
< count
) && (ORDER(array
[i
].obj
, anObject
) >= 0);
212 return( setObject(i
, anObject
));
215 void OSOrderedSet::removeObject(const OSMetaClassBase
*anObject
)
217 bool deleted
= false;
220 for (i
= 0; i
< count
; i
++) {
223 array
[i
-1] = array
[i
];
224 else if( (array
[i
].obj
== anObject
)) {
225 array
[i
].obj
->taggedRelease(OSTypeID(OSCollection
));
236 bool OSOrderedSet::containsObject(const OSMetaClassBase
*anObject
) const
238 return anObject
&& member(anObject
);
241 bool OSOrderedSet::member(const OSMetaClassBase
*anObject
) const
246 (i
< count
) && (array
[i
].obj
!= anObject
);
253 OSObject
*OSOrderedSet::getObject( unsigned int index
) const
259 // *pri = array[index].pri;
261 return( (OSObject
*) array
[index
].obj
);
264 OSObject
*OSOrderedSet::getFirstObject() const
267 return( (OSObject
*) array
[0].obj
);
272 OSObject
*OSOrderedSet::getLastObject() const
275 return( (OSObject
*) array
[count
-1].obj
);
280 SInt32
OSOrderedSet::orderObject( const OSMetaClassBase
* anObject
)
282 return( ORDER( anObject
, 0 ));
285 void *OSOrderedSet::getOrderingRef()
290 bool OSOrderedSet::isEqualTo(const OSOrderedSet
*anOrderedSet
) const
294 if ( this == anOrderedSet
)
297 if ( count
!= anOrderedSet
->getCount() )
300 for ( i
= 0; i
< count
; i
++ ) {
301 if ( !array
[i
].obj
->isEqualTo(anOrderedSet
->getObject(i
)) )
308 bool OSOrderedSet::isEqualTo(const OSMetaClassBase
*anObject
) const
312 oSet
= OSDynamicCast(OSOrderedSet
, anObject
);
314 return isEqualTo(oSet
);
319 unsigned int OSOrderedSet::iteratorSize() const
321 return( sizeof(unsigned int));
324 bool OSOrderedSet::initIterator(void *inIterator
) const
326 unsigned int *iteratorP
= (unsigned int *) inIterator
;
333 getNextObjectForIterator(void *inIterator
, OSObject
**ret
) const
335 unsigned int *iteratorP
= (unsigned int *) inIterator
;
336 unsigned int index
= (*iteratorP
)++;
339 *ret
= (OSObject
*) array
[index
].obj
;