Selaa lähdekoodia

structure/CAvl: implement range queries via CAvl_GetFirstGreater etc.

ambrop7 13 vuotta sitten
vanhempi
sitoutus
53e2c29355
4 muutettua tiedostoa jossa 88 lisäystä ja 0 poistoa
  1. 4 0
      structure/CAvl_decl.h
  2. 4 0
      structure/CAvl_footer.h
  3. 4 0
      structure/CAvl_header.h
  4. 76 0
      structure/CAvl_impl.h

+ 4 - 0
structure/CAvl_decl.h

@@ -52,6 +52,10 @@ static void CAvl_Remove (CAvl *o, CAvlArg arg, CAvlRef node);
 #if !CAVL_PARAM_FEATURE_KEYS_ARE_INDICES && !CAVL_PARAM_FEATURE_NOKEYS
 static CAvlRef CAvl_Lookup (const CAvl *o, CAvlArg arg, CAvlKey key);
 static CAvlRef CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key);
+static CAvlRef CAvl_GetFirstGreater (const CAvl *o, CAvlArg arg, CAvlKey key);
+static CAvlRef CAvl_GetLastLesser (const CAvl *o, CAvlArg arg, CAvlKey key);
+static CAvlRef CAvl_GetFirstGreaterEqual (const CAvl *o, CAvlArg arg, CAvlKey key);
+static CAvlRef CAvl_GetLastLesserEqual (const CAvl *o, CAvlArg arg, CAvlKey key);
 #endif
 static CAvlRef CAvl_GetFirst (const CAvl *o, CAvlArg arg);
 static CAvlRef CAvl_GetLast (const CAvl *o, CAvlArg arg);

+ 4 - 0
structure/CAvl_footer.h

@@ -64,6 +64,10 @@
 #undef CAvl_Remove
 #undef CAvl_Lookup
 #undef CAvl_LookupExact
+#undef CAvl_GetFirstGreater
+#undef CAvl_GetLastLesser
+#undef CAvl_GetFirstGreaterEqual
+#undef CAvl_GetLastLesserEqual
 #undef CAvl_GetFirst
 #undef CAvl_GetLast
 #undef CAvl_GetNext

+ 4 - 0
structure/CAvl_header.h

@@ -84,6 +84,10 @@
 #define CAvl_Remove MERGE(CAvl, _Remove)
 #define CAvl_Lookup MERGE(CAvl, _Lookup)
 #define CAvl_LookupExact MERGE(CAvl, _LookupExact)
+#define CAvl_GetFirstGreater MERGE(CAvl, _GetFirstGreater)
+#define CAvl_GetLastLesser MERGE(CAvl, _GetLastLesser)
+#define CAvl_GetFirstGreaterEqual MERGE(CAvl, _GetFirstGreaterEqual)
+#define CAvl_GetLastLesserEqual MERGE(CAvl, _GetLastLesserEqual)
 #define CAvl_GetFirst MERGE(CAvl, _GetFirst)
 #define CAvl_GetLast MERGE(CAvl, _GetLast)
 #define CAvl_GetNext MERGE(CAvl, _GetNext)

+ 76 - 0
structure/CAvl_impl.h

@@ -638,6 +638,82 @@ static CAvlRef CAvl_LookupExact (const CAvl *o, CAvlArg arg, CAvlKey key)
     }
 }
 
+static CAvlRef CAvl_GetFirstGreater (const CAvl *o, CAvlArg arg, CAvlKey key)
+{
+    CAvlRef c = CAvl_Lookup(o, arg, key);
+    if (CAvlIsNullRef(c)) {
+        return CAvl_nullref();
+    }
+    
+    if (CAvl_compare_key_entry(arg, key, c) >= 0) {
+        c = CAvl_GetNext(o, arg, c);
+        if (CAvlIsNullRef(c)) {
+            return CAvl_nullref();
+        }
+    }
+    
+    ASSERT(CAvl_compare_key_entry(arg, key, c) < 0);
+    
+    return c;
+}
+
+static CAvlRef CAvl_GetLastLesser (const CAvl *o, CAvlArg arg, CAvlKey key)
+{
+    CAvlRef c = CAvl_Lookup(o, arg, key);
+    if (CAvlIsNullRef(c)) {
+        return CAvl_nullref();
+    }
+    
+    if (CAvl_compare_key_entry(arg, key, c) <= 0) {
+        c = CAvl_GetPrev(o, arg, c);
+        if (CAvlIsNullRef(c)) {
+            return CAvl_nullref();
+        }
+    }
+    
+    ASSERT(CAvl_compare_key_entry(arg, key, c) > 0);
+    
+    return c;
+}
+
+static CAvlRef CAvl_GetFirstGreaterEqual (const CAvl *o, CAvlArg arg, CAvlKey key)
+{
+    CAvlRef c = CAvl_Lookup(o, arg, key);
+    if (CAvlIsNullRef(c)) {
+        return CAvl_nullref();
+    }
+    
+    if (CAvl_compare_key_entry(arg, key, c) > 0) {
+        c = CAvl_GetNext(o, arg, c);
+        if (CAvlIsNullRef(c)) {
+            return CAvl_nullref();
+        }
+    }
+    
+    ASSERT(CAvl_compare_key_entry(arg, key, c) <= 0);
+    
+    return c;
+}
+
+static CAvlRef CAvl_GetLastLesserEqual (const CAvl *o, CAvlArg arg, CAvlKey key)
+{
+    CAvlRef c = CAvl_Lookup(o, arg, key);
+    if (CAvlIsNullRef(c)) {
+        return CAvl_nullref();
+    }
+    
+    if (CAvl_compare_key_entry(arg, key, c) < 0) {
+        c = CAvl_GetPrev(o, arg, c);
+        if (CAvlIsNullRef(c)) {
+            return CAvl_nullref();
+        }
+    }
+    
+    ASSERT(CAvl_compare_key_entry(arg, key, c) >= 0);
+    
+    return c;
+}
+
 #endif
 
 static CAvlRef CAvl_GetFirst (const CAvl *o, CAvlArg arg)